ROOT logo
// @(#)root/xml:$Id: TXMLFile.cxx 25450 2008-09-18 21:13:42Z pcanal $
// Author: Sergey Linev, Rene Brun  10.05.2004

/*************************************************************************
 * Copyright (C) 1995-2004, 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. One of possible approach with code generation
// is implemented in TXMLPlayer class.
//
// 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 TDirectoryFile::WriteObject and
// TDirectoryFile::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 is enabled by default
//
// documentation
// =============
// See also classes TBufferXML, TKeyXML, TXMLEngine, TXMLSetup and TXMLPlayer.
// 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 "TSystem.h"
#include "TList.h"
#include "TBrowser.h"
#include "TObjArray.h"
#include "TBufferXML.h"
#include "TKeyXML.h"
#include "TObjArray.h"
#include "TArrayC.h"
#include "TStreamerInfo.h"
#include "TStreamerElement.h"
#include "TProcessID.h"
#include "TError.h"
#include "TClass.h"

ClassImp(TXMLFile);

//______________________________________________________________________________
TXMLFile::TXMLFile() :
   TFile(),
   TXMLSetup(),
   fDoc(0),
   fStreamerInfoNode(0),
   fXML(0),
   fKeyCounter(0)
{
   // default TXMLFile constructor
   
   SetBit(kBinaryFile, kFALSE);
}


//______________________________________________________________________________
TXMLFile::TXMLFile(const char* filename, Option_t* option, const char* title, Int_t compression) :
   TFile(),
   TXMLSetup(),
   fDoc(0),
   fStreamerInfoNode(0),
   fXML(0),
   fKeyCounter(0)
{
   // Open or creates local XML file with name filename.
   // It is recommended to specify filename as "<file>.xml". The suffix ".xml"
   // will be used by object browsers to automatically identify the file as
   // a XML file. If the constructor fails in any way IsZombie() will
   // return true. Use IsOpen() to check if the file is (still) open.
   //
   // If option = NEW or CREATE   create a new file and open it for writing,
   //                             if the file already exists the file is
   //                             not opened.
   //           = RECREATE        create a new file, if the file already
   //                             exists it will be overwritten.
   //           = 2xoo            create a new file with specified xml settings
   //                             for more details see TXMLSetup class
   //           = UPDATE          open an existing file for writing.
   //                             if no file exists, it is created.
   //           = READ            open an existing file for reading.
   //
   // For more details see comments for TFile::TFile() constructor
   //
   // For a moment TXMLFile does not support TTree objects and subdirectories

   fXML = new TXMLEngine();

   if (!gROOT)
      ::Fatal("TFile::TFile", "ROOT system not initialized");

   if (!strncmp(filename, "xml:", 4))
      filename += 4;

   gDirectory = 0;
   SetName(filename);
   SetTitle(title);
   TDirectoryFile::Build(this, 0);

   fD          = -1;
   fFile       = this;
   fFree       = 0;
   fVersion    = gROOT->GetVersionInt();  //ROOT version in integer format
   fUnits      = 4;
   fOption     = option;
   SetCompressionLevel(compression);
   fWritten    = 0;
   fSumBuffer  = 0;
   fSum2Buffer = 0;
   fBytesRead  = 0;
   fBytesWrite = 0;
   fClassIndex = 0;
   fSeekInfo   = 0;
   fNbytesInfo = 0;
   fProcessIDs = 0;
   fNProcessIDs= 0;
   fIOVersion  = TXMLFile::Class_Version();
   SetBit(kBinaryFile, kFALSE);

   fOption = option;
   fOption.ToUpper();

   if (fOption == "NEW") fOption = "CREATE";

   Bool_t create   = (fOption == "CREATE") ? kTRUE : kFALSE;
   Bool_t recreate = (fOption == "RECREATE") ? kTRUE : kFALSE;
   Bool_t update   = (fOption == "UPDATE") ? kTRUE : kFALSE;
   Bool_t read     = (fOption == "READ") ? kTRUE : kFALSE;
   Bool_t xmlsetup = IsValidXmlSetup(option);
   if (xmlsetup) recreate = kTRUE;

   if (!create && !recreate && !update && !read) {
      read    = kTRUE;
      fOption = "READ";
   }

   Bool_t devnull = kFALSE;
   const char *fname = 0;

   if (!filename || !strlen(filename)) {
      Error("TXMLFile", "file name is not specified");
      goto zombie;
   }

   // support dumping to /dev/null on UNIX
   if (!strcmp(filename, "/dev/null") &&
       !gSystem->AccessPathName(filename, kWritePermission)) {
      devnull  = kTRUE;
      create   = kTRUE;
      recreate = kFALSE;
      update   = kFALSE;
      read     = kFALSE;
      fOption  = "CREATE";
      SetBit(TFile::kDevNull);
   }

   gROOT->cd();

   fname = gSystem->ExpandPathName(filename);
   if (fname) {
      SetName(fname);
      delete [] (char*)fname;
      fname = GetName();
   } else {
      Error("TXMLFile", "error expanding path %s", filename);
      goto zombie;
   }

   if (recreate) {
      if (!gSystem->AccessPathName(fname, kFileExists))
         gSystem->Unlink(fname);
      recreate = kFALSE;
      create   = kTRUE;
      fOption  = "CREATE";
   }

   if (create && !devnull && !gSystem->AccessPathName(fname, kFileExists)) {
      Error("TXMLFile", "file %s already exists", fname);
      goto zombie;
   }

   if (update) {
      if (gSystem->AccessPathName(fname, kFileExists)) {
         update = kFALSE;
         create = kTRUE;
      }
      if (update && gSystem->AccessPathName(fname, kWritePermission)) {
         Error("TXMLFile", "no write permission, could not open file %s", fname);
         goto zombie;
      }
   }

   if (read) {
      if (gSystem->AccessPathName(fname, kFileExists)) {
         Error("TXMLFile", "file %s does not exist", fname);
         goto zombie;
      }
      if (gSystem->AccessPathName(fname, kReadPermission)) {
         Error("TXMLFile", "no read permission, could not open file %s", fname);
         goto zombie;
      }
   }

   fRealName = fname;

   if (create || update)
      SetWritable(kTRUE);
   else
      SetWritable(kFALSE);

   if (create) {
      if (xmlsetup)
         ReadSetupFromStr(option);
      else
         ReadSetupFromStr(TXMLSetup::DefaultXmlSetup());
   }

   InitXmlFile(create);

   return;

zombie:
   MakeZombie();
   gDirectory = gROOT;
}

//______________________________________________________________________________
void TXMLFile::InitXmlFile(Bool_t create)
{
   // initialize xml file and correspondent structures
   // identical to TFile::Init() function

   Int_t len = gROOT->GetListOfStreamerInfo()->GetSize()+1;
   if (len<5000) len = 5000;
   fClassIndex = new TArrayC(len);
   fClassIndex->Reset(0);

   if (create) {
      fDoc = fXML->NewDoc();
      XMLNodePointer_t fRootNode = fXML->NewChild(0, 0, xmlio::Root, 0);
      fXML->DocSetRootElement(fDoc, fRootNode);
   } else {
      ReadFromFile();
   }

   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);
}

//______________________________________________________________________________
void TXMLFile::Close(Option_t *option)
{
   // Close a XML file
   // For more comments see TFile::Close() function

   if (!IsOpen()) return;

   TString opt = option;
   if (opt.Length()>0)
      opt.ToLower();

   if (IsWritable()) SaveToFile();

   fWritable = kFALSE;

   if (fDoc) {
      fXML->FreeDoc(fDoc);
      fDoc = 0;
   }

   if (fClassIndex) {
      delete fClassIndex;
      fClassIndex = 0;
   }

   if (fStreamerInfoNode) {
      fXML->FreeNode(fStreamerInfoNode);
      fStreamerInfoNode = 0;
   }

   TDirectory *cursav = gDirectory;
   cd();

   if (cursav == this || cursav->GetFile() == this) {
      cursav = 0;
   }

   // Delete all supported directories structures from memory
   TDirectoryFile::Close();
   cd();      // Close() sets gFile = 0

   if (cursav)
      cursav->cd();
   else {
      gFile      = 0;
      gDirectory = gROOT;
   }

   //delete the TProcessIDs
   TList pidDeleted;
   TIter next(fProcessIDs);
   TProcessID *pid;
   while ((pid = (TProcessID*)next())) {
      if (!pid->DecrementCount()) {
         if (pid != TProcessID::GetSessionProcessID()) pidDeleted.Add(pid);
      } else if(opt.Contains("r")) {
         pid->Clear();
      }
   }
   pidDeleted.Delete();

   gROOT->GetListOfFiles()->Remove(this);
}

//______________________________________________________________________________
TXMLFile::~TXMLFile()
{
   // destructor of TXMLFile object

   Close();

   if (fXML!=0) {
      delete fXML;
      fXML = 0;
   }
}

//______________________________________________________________________________
void TXMLFile::operator=(const TXMLFile &)
{
   // make private to exclude copy operator
}

//______________________________________________________________________________
Bool_t TXMLFile::IsOpen() const
{
   // return kTRUE if file is opened and can be accessed

   return fDoc != 0;
}

//______________________________________________________________________________
Int_t TXMLFile::ReOpen(Option_t* mode)
{
   // Reopen a file with a different access mode, like from READ to
   // See TFile::Open() for details

   cd();

   TString opt = mode;
   opt.ToUpper();

   if (opt != "READ" && opt != "UPDATE") {
      Error("ReOpen", "mode must be either READ or UPDATE, not %s", opt.Data());
      return 1;
   }

   if (opt == fOption || (opt == "UPDATE" && fOption == "CREATE"))
      return 1;

   if (opt == "READ") {
      // switch to READ mode

      if (IsOpen() && IsWritable())
         SaveToFile();
      fOption = opt;

      SetWritable(kFALSE);

   } else {
      fOption = opt;

      SetWritable(kTRUE);
   }

   return 0;
}

//______________________________________________________________________________
TKey* TXMLFile::CreateKey(TDirectory* mother, const TObject* obj, const char* name, Int_t)
{
   // create XML key, which will store object in xml structures

   return new TKeyXML(mother, ++fKeyCounter, obj, name);
}

//______________________________________________________________________________
TKey* TXMLFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t)
{
   // create XML key, which will store object in xml structures

   return new TKeyXML(mother, ++fKeyCounter, obj, cl, name);
}

//______________________________________________________________________________
void TXMLFile::ProduceFileNames(const char* filename, TString& fname, TString& dtdname)
{
   // function produces pair of xml and dtd file names

   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()
{
   // Saves xml structures to file
   // xml elements are kept in list of TKeyXML objects
   // When saving, all this elements are linked to root xml node
   // In the end StreamerInfo structures are added
   // After xml document is saved, all nodes will be unlinked from root node
   // and kept in memory.
   // Only Close() or destructor relase memory, used by xml structures

   if (fDoc==0) return;

   if (gDebug>1)
      Info("SaveToFile","File: %s",fRealName.Data());

   XMLNodePointer_t fRootNode = fXML->DocGetRootElement(fDoc);

   fXML->FreeAttr(fRootNode, xmlio::Setup);
   fXML->NewAttr(fRootNode, 0, xmlio::Setup, GetSetupAsString());

   fXML->FreeAttr(fRootNode, xmlio::Ref);
   fXML->NewAttr(fRootNode, 0, xmlio::Ref, xmlio::Null);
   
   if (GetIOVersion()>1) {
   
      fXML->FreeAttr(fRootNode, xmlio::CreateTm);
      fXML->NewAttr(fRootNode, 0, xmlio::CreateTm, fDatimeC.AsSQLString());
   
      fXML->FreeAttr(fRootNode, xmlio::ModifyTm);
      fXML->NewAttr(fRootNode, 0, xmlio::ModifyTm, fDatimeM.AsSQLString());
   
      fXML->FreeAttr(fRootNode, xmlio::ObjectUUID);
      fXML->NewAttr(fRootNode, 0, xmlio::ObjectUUID, fUUID.AsString());
      
      fXML->FreeAttr(fRootNode, xmlio::Title);
      if (strlen(GetTitle())>0)
         fXML->NewAttr(fRootNode, 0, xmlio::Title, GetTitle());

      fXML->FreeAttr(fRootNode, xmlio::IOVersion);
      fXML->NewIntAttr(fRootNode, xmlio::IOVersion, GetIOVersion());
   }

   TString fname, dtdname;
   ProduceFileNames(fRealName, fname, dtdname);

/*
   TIter iter(GetListOfKeys());
   TKeyXML* key = 0;
   while ((key=(TKeyXML*)iter()) !=0)
      fXML->AddChild(fRootNode, key->KeyNode());
*/      

   CombineNodesTree(this, fRootNode, kTRUE);

   WriteStreamerInfo();

   if (fStreamerInfoNode)
      fXML->AddChild(fRootNode, fStreamerInfoNode);

   Int_t layout = GetCompressionLevel()>5 ? 0 : 1;

   fXML->SaveDoc(fDoc, fname, layout);

/*   iter.Reset();
   while ((key=(TKeyXML*)iter()) !=0)
      fXML->UnlinkNode(key->KeyNode());
*/
   CombineNodesTree(this, fRootNode, kFALSE);

   if (fStreamerInfoNode)
      fXML->UnlinkNode(fStreamerInfoNode);
}

//______________________________________________________________________________
void TXMLFile::CombineNodesTree(TDirectory* dir, XMLNodePointer_t topnode, Bool_t dolink)
{
   // Connect/disconnect all file nodes to single tree before/after saving
   
   if (dir==0) return;
   
   TIter iter(dir->GetListOfKeys());
   TKeyXML* key = 0;

   while ((key=(TKeyXML*)iter()) !=0) {
      if (dolink)
         fXML->AddChild(topnode, key->KeyNode());
      else 
         fXML->UnlinkNode(key->KeyNode());   
      if (key->IsSubdir()) 
         CombineNodesTree(FindKeyDir(dir, key->GetKeyId()), key->KeyNode(), dolink);
   }
}


//______________________________________________________________________________
Bool_t TXMLFile::ReadFromFile()
{
   // read document from file
   // Now full content of docuument reads into the memory
   // Then document decomposed to separate keys and streamer info structures
   // All inrelevant data will be cleaned

   fDoc = fXML->ParseFile(fRealName);
   if (fDoc==0) return kFALSE;

   XMLNodePointer_t fRootNode = fXML->DocGetRootElement(fDoc);
   
   if ((fRootNode==0) || !fXML->ValidateVersion(fDoc)) {
      fXML->FreeDoc(fDoc);
      fDoc=0;
      return kFALSE;
   }

   ReadSetupFromStr(fXML->GetAttr(fRootNode, xmlio::Setup));
   
   if (fXML->HasAttr(fRootNode, xmlio::CreateTm)) {
      TDatime tm(fXML->GetAttr(fRootNode, xmlio::CreateTm)); 
      fDatimeC = tm;
   }

   if (fXML->HasAttr(fRootNode, xmlio::ModifyTm)) {
      TDatime tm(fXML->GetAttr(fRootNode, xmlio::ModifyTm)); 
      fDatimeM = tm;
   }

   if (fXML->HasAttr(fRootNode, xmlio::ObjectUUID)) {
      TUUID id(fXML->GetAttr(fRootNode, xmlio::ObjectUUID));
      fUUID = id;
   }
   
   if (fXML->HasAttr(fRootNode, xmlio::Title)) 
      SetTitle(fXML->GetAttr(fRootNode, xmlio::Title));
      
   if (fXML->HasAttr(fRootNode, xmlio::IOVersion)) 
      fIOVersion = fXML->GetIntAttr(fRootNode, xmlio::IOVersion);
   else
      fIOVersion = 1;   

   fStreamerInfoNode = fXML->GetChild(fRootNode);
   fXML->SkipEmpty(fStreamerInfoNode);
   while (fStreamerInfoNode!=0) {
      if (strcmp(xmlio::SInfos, fXML->GetNodeName(fStreamerInfoNode))==0) break;
      fXML->ShiftToNext(fStreamerInfoNode);
   }
   fXML->UnlinkNode(fStreamerInfoNode);

   if (fStreamerInfoNode!=0)
      ReadStreamerInfo();

   if (IsUseDtd())
      if (!fXML->ValidateDocument(fDoc, gDebug>0)) {
         fXML->FreeDoc(fDoc);
         fDoc=0;
         return kFALSE;
      }

   ReadKeysList(this, fRootNode);

   fXML->CleanNode(fRootNode);
   
   return kTRUE;
}

//______________________________________________________________________________
Int_t TXMLFile::ReadKeysList(TDirectory* dir, XMLNodePointer_t topnode)
{
   // Read list of keys for directory
   
   if ((dir==0) || (topnode==0)) return 0;
   
   Int_t nkeys = 0;
   
   XMLNodePointer_t keynode = fXML->GetChild(topnode);
   fXML->SkipEmpty(keynode);
   while (keynode!=0) {
      XMLNodePointer_t next = fXML->GetNext(keynode);

      if (strcmp(xmlio::Xmlkey, fXML->GetNodeName(keynode))==0) {
         fXML->UnlinkNode(keynode);

         TKeyXML* key = new TKeyXML(dir, ++fKeyCounter, keynode);
         dir->AppendKey(key);

         if (gDebug>2)
            Info("ReadKeysList","Add key %s from node %s",key->GetName(), fXML->GetNodeName(keynode));
            
         nkeys++;
      }

      keynode = next;
      fXML->SkipEmpty(keynode);
   }
   
   return nkeys;
}

//______________________________________________________________________________
void TXMLFile::WriteStreamerInfo()
{
   // convert all TStreamerInfo, used in file, to xml format

   if (fStreamerInfoNode) {
      fXML->FreeNode(fStreamerInfoNode);
      fStreamerInfoNode = 0;
   }

   if (!IsStoreStreamerInfos()) return;

   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;

   fStreamerInfoNode = fXML->NewChild(0, 0, xmlio::SInfos);
   for (int n=0;n<=list.GetLast();n++) {
      info  = (TStreamerInfo*) list.At(n);

      XMLNodePointer_t infonode = fXML->NewChild(fStreamerInfoNode, 0, "TStreamerInfo");

      fXML->NewAttr(infonode, 0, "name", info->GetName());
      fXML->NewAttr(infonode, 0, "title", info->GetTitle());

      fXML->NewIntAttr(infonode, "v", info->IsA()->GetClassVersion());
      fXML->NewIntAttr(infonode, "classversion", info->GetClassVersion());
      fXML->NewAttr(infonode, 0, "canoptimize", (info->TestBit(TStreamerInfo::kCannotOptimize) ? xmlio::False : xmlio::True));
      fXML->NewIntAttr(infonode, "checksum", info->GetCheckSum());

      TIter iter2(info->GetElements());
      TStreamerElement* elem=0;
      while ((elem= (TStreamerElement*) iter2()) != 0) {
         StoreStreamerElement(infonode, elem);
      }
   }
}

//______________________________________________________________________________
TList* TXMLFile::GetStreamerInfoList()
{
   // Read streamerinfo structures from xml format and provide them in the list
   // It is user responsibility to destroy this list

   if (fStreamerInfoNode==0) return 0;

   TList* list = new TList();

   XMLNodePointer_t sinfonode = fXML->GetChild(fStreamerInfoNode);
   fXML->SkipEmpty(sinfonode);

   while (sinfonode!=0) {
      if (strcmp("TStreamerInfo",fXML->GetNodeName(sinfonode))==0) {
         TString fname = fXML->GetAttr(sinfonode,"name");
         TString ftitle = fXML->GetAttr(sinfonode,"title");

         TStreamerInfo* info = new TStreamerInfo(TClass::GetClass(fname));
         info->SetTitle(ftitle);

         list->Add(info);

         Int_t clversion = AtoI(fXML->GetAttr(sinfonode,"classversion"));
         info->SetClassVersion(clversion);
         Int_t checksum = AtoI(fXML->GetAttr(sinfonode,"checksum"));
         info->SetCheckSum(checksum);

         const char* canoptimize = fXML->GetAttr(sinfonode,"canoptimize");
         if ((canoptimize==0) || (strcmp(canoptimize,xmlio::False)==0))
            info->SetBit(TStreamerInfo::kCannotOptimize);
         else
            info->ResetBit(TStreamerInfo::kCannotOptimize);

         XMLNodePointer_t node = fXML->GetChild(sinfonode);
         fXML->SkipEmpty(node);
         while (node!=0) {
            ReadStreamerElement(node, info);
            fXML->ShiftToNext(node);
         }
      }
      fXML->ShiftToNext(sinfonode);
   }

   list->SetOwner();

   return list;
}

//______________________________________________________________________________
void TXMLFile::StoreStreamerElement(XMLNodePointer_t infonode, TStreamerElement* elem)
{
   // store data of single TStreamerElement in streamer node

   TClass* cl = elem->IsA();

   XMLNodePointer_t node = fXML->NewChild(infonode, 0, cl->GetName());

   char sbuf[100], namebuf[100];

   fXML->NewAttr(node,0,"name",elem->GetName());
   if (strlen(elem->GetTitle())>0)
      fXML->NewAttr(node,0,"title",elem->GetTitle());

   fXML->NewIntAttr(node, "v", cl->GetClassVersion());

   fXML->NewIntAttr(node, "type", elem->GetType());

   if (strlen(elem->GetTypeName())>0)
      fXML->NewAttr(node,0,"typename", elem->GetTypeName());

   fXML->NewIntAttr(node, "size", elem->GetSize());

   if (elem->GetArrayDim()>0) {
      fXML->NewIntAttr(node, "numdim", elem->GetArrayDim());

      for (int ndim=0;ndim<elem->GetArrayDim();ndim++) {
         sprintf(namebuf, "dim%d", ndim);
         fXML->NewIntAttr(node, namebuf, elem->GetMaxIndex(ndim));
      }
   }

   if (cl == TStreamerBase::Class()) {
      TStreamerBase* base = (TStreamerBase*) elem;
      sprintf(sbuf, "%d", base->GetBaseVersion());
      fXML->NewAttr(node,0, "baseversion", sbuf);
   } else
   if (cl == TStreamerBasicPointer::Class()) {
      TStreamerBasicPointer* bptr = (TStreamerBasicPointer*) elem;
      fXML->NewIntAttr(node, "countversion", bptr->GetCountVersion());
      fXML->NewAttr(node, 0, "countname", bptr->GetCountName());
      fXML->NewAttr(node, 0, "countclass", bptr->GetCountClass());
   } else
   if (cl == TStreamerLoop::Class()) {
      TStreamerLoop* loop = (TStreamerLoop*) elem;
      fXML->NewIntAttr(node, "countversion", loop->GetCountVersion());
      fXML->NewAttr(node, 0, "countname", loop->GetCountName());
      fXML->NewAttr(node, 0, "countclass", loop->GetCountClass());
   } else
   if ((cl == TStreamerSTL::Class()) || (cl == TStreamerSTLstring::Class())) {
      TStreamerSTL* stl = (TStreamerSTL*) elem;
      fXML->NewIntAttr(node, "STLtype", stl->GetSTLtype());
      fXML->NewIntAttr(node, "Ctype", stl->GetCtype());
   }
}

//______________________________________________________________________________
void TXMLFile::ReadStreamerElement(XMLNodePointer_t node, TStreamerInfo* info)
{
  // read and reconstruct single TStreamerElement from xml node

   TClass* cl = TClass::GetClass(fXML->GetNodeName(node));
   if ((cl==0) || !cl->InheritsFrom(TStreamerElement::Class())) return;

   TStreamerElement* elem = (TStreamerElement*) cl->New();

   int elem_type = fXML->GetIntAttr(node,"type");

   elem->SetName(fXML->GetAttr(node,"name"));
   elem->SetTitle(fXML->GetAttr(node,"title"));
   elem->SetType(elem_type);
   elem->SetTypeName(fXML->GetAttr(node,"typename"));
   elem->SetSize(fXML->GetIntAttr(node,"size"));


   if (cl == TStreamerBase::Class()) {
      int basever = fXML->GetIntAttr(node,"baseversion");
      ((TStreamerBase*) elem)->SetBaseVersion(basever);
   } else
   if (cl == TStreamerBasicPointer::Class()) {
      TString countname = fXML->GetAttr(node,"countname");
      TString countclass = fXML->GetAttr(node,"countclass");
      Int_t countversion = fXML->GetIntAttr(node, "countversion");

      ((TStreamerBasicPointer*)elem)->SetCountVersion(countversion);
      ((TStreamerBasicPointer*)elem)->SetCountName(countname);
      ((TStreamerBasicPointer*)elem)->SetCountClass(countclass);
   } else
   if (cl == TStreamerLoop::Class()) {
      TString countname = fXML->GetAttr(node,"countname");
      TString countclass = fXML->GetAttr(node,"countclass");
      Int_t countversion = fXML->GetIntAttr(node,"countversion");
      ((TStreamerLoop*)elem)->SetCountVersion(countversion);
      ((TStreamerLoop*)elem)->SetCountName(countname);
      ((TStreamerLoop*)elem)->SetCountClass(countclass);
   } else
   if ((cl == TStreamerSTL::Class()) || (cl == TStreamerSTLstring::Class()))  {
      int fSTLtype = fXML->GetIntAttr(node,"STLtype");
      int fCtype = fXML->GetIntAttr(node,"Ctype");
      ((TStreamerSTL*)elem)->SetSTLtype(fSTLtype);
      ((TStreamerSTL*)elem)->SetCtype(fCtype);
   }

   char namebuf[100];

   if (fXML->HasAttr(node, "numdim") && (elem!=0)) {
      int numdim = fXML->GetIntAttr(node,"numdim");
      elem->SetArrayDim(numdim);
      for (int ndim=0;ndim<numdim;ndim++) {
         sprintf(namebuf, "dim%d", ndim);
         int maxi = fXML->GetIntAttr(node, namebuf);
         elem->SetMaxIndex(ndim, maxi);
      }
   }

   elem->SetType(elem_type);
   elem->SetNewType(elem_type);

   info->GetElements()->Add(elem);
}

//______________________________________________________________________________
void TXMLFile::SetXmlLayout(EXMLLayout layout)
{
   // Change layout of objects in xml file
   // Can be changed only for newly created file.
   //
   // Currently there are two supported layouts:
   //
   // TXMLSetup::kSpecialized = 2
   //    This is default layout of the file, when xml nodes names class names and data member
   //    names are used. For instance:
   //          <TAttLine version="1">
   //            <fLineColor v="1"/>
   //            <fLineStyle v="1"/>
   //            <fLineWidth v="1"/>
   //          </TAttLine>
   //
   // TXMLSetup::kGeneralized = 3
   //    For this layout all nodes name does not depend from class definitions.
   //    The same class looks like
   //          <Class name="TAttLine" version="1">
   //            <Member name="fLineColor" v="1"/>
   //            <Member name="fLineStyle" v="1"/>
   //            <Member name="fLineWidth" v="1"/>
   //          </Member>
   //

   if (IsWritable() && (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetXmlLayout(layout);
}

//______________________________________________________________________________
void TXMLFile::SetStoreStreamerInfos(Bool_t iConvert)
{
   // If true, all correspondent to file TStreamerInfo objects will be stored in file
   // this allows to apply schema avolution later for this file
   // may be usefull, when file used outside ROOT and TStreamerInfo objects does not required
   // Can be changed only for newly created file.

   if (IsWritable() &&  (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetStoreStreamerInfos(iConvert);
}

//______________________________________________________________________________
void TXMLFile::SetUsedDtd(Bool_t use)
{
   // Specify usage of DTD for this file.
   // Currently this option not avaliable (always false).
   // Can be changed only for newly created file.

   if (IsWritable() &&  (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetUsedDtd(use);
}

//______________________________________________________________________________
void TXMLFile::SetUseNamespaces(Bool_t iUseNamespaces)
{
   // Specifiy usage of namespaces in xml file
   // In current implementation every instrumented class in file gets its unique namespace,
   // which is equal to name of class and refer to root documentation page like
   // <TAttPad xmlns:TAttPad="http://root.cern.ch/root/htmldoc/TAttPad.html" version="3">
   // And xml node for class member gets its name as combination of class name and member name
   //            <TAttPad:fLeftMargin v="0.100000"/>
   //            <TAttPad:fRightMargin v="0.100000"/>
   //            <TAttPad:fBottomMargin v="0.100000"/>
   //            and so on
   // Usage of namespace increase size of xml file, but makes file more readable
   // and allows to produce DTD in the case, when in several classes data member has same name
   // Can be changed only for newly created file.

   if (IsWritable() && (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetUseNamespaces(iUseNamespaces);
}

//______________________________________________________________________________
Bool_t TXMLFile::AddXmlComment(const char* comment)
{
   // Add comment line on the top of the xml document 
   // This line can only be seen in xml editor and cannot be accessed later 
   // with TXMLFile methods
   
   if (!IsWritable() || (fXML==0)) return kFALSE;
   
   return fXML->AddDocComment(fDoc, comment);
}


//______________________________________________________________________________
Bool_t TXMLFile::AddXmlStyleSheet(const char* href, 
                                  const char* type,
                                  const char* title,
                                  int alternate,
                                  const char* media,
                                  const char* charset)
{
   // Adds style sheet definition on the top of xml document
   // Creates <?xml-stylesheet alternate="yes" title="compact" href="small-base.css" type="text/css"?>
   // Attributes href and type must be supplied, 
   //  other attributes: title, alternate, media, charset are optional
   // if alternate==0, attribyte alternate="no" will be created,
   // if alternate>0, attribute alternate="yes"
   // if alternate<0, attribute will not be created
   // This style sheet definition cannot be later access with TXMLFile methods.

   if (!IsWritable() || (fXML==0)) return kFALSE;
    
   return fXML->AddDocStyleSheet(fDoc, href,type,title,alternate,media,charset);
}                                  

//______________________________________________________________________________
Bool_t TXMLFile::AddXmlLine(const char* line)
{
   // Add just one line on the top of xml document
   // For instance, line can contain special xml processing instructions
   // Line should has correct xml syntax that later it can be decoded by xml parser
   // To be parsed later by TXMLFile again, this line should contain either
   // xml comments or xml processing instruction
   
   if (!IsWritable() || (fXML==0)) return kFALSE;

   return fXML->AddDocRawLine(fDoc, line); 
}

//______________________________________________________________________________
Long64_t TXMLFile::DirCreateEntry(TDirectory* dir)
{
   // Create key for directory entry in the key

   TDirectory* mother = dir->GetMotherDir();
   if (mother==0) mother = this;

   TKeyXML* key = new TKeyXML(mother, ++fKeyCounter, dir, dir->GetName(), dir->GetTitle());
   
   key->SetSubir();
   
   return key->GetKeyId();
}

//______________________________________________________________________________
TKeyXML* TXMLFile::FindDirKey(TDirectory* dir)
{
   // Serach for key which correspond to direcory dir
   
   TDirectory* motherdir = dir->GetMotherDir();
   if (motherdir==0) motherdir = this;

   TIter next(motherdir->GetListOfKeys());
   TObject* obj = 0;
   
   while ((obj = next())!=0) {
      TKeyXML* key = dynamic_cast<TKeyXML*> (obj);
      
      if (key!=0)
         if (key->GetKeyId()==dir->GetSeekDir()) return key;
   }
   
   return 0;
}


//______________________________________________________________________________
TDirectory* TXMLFile::FindKeyDir(TDirectory* motherdir, Long64_t keyid)
{
   //Find a directory in motherdir with a seek equal to keyid
   if (motherdir==0) motherdir = this;
   
   TIter next(motherdir->GetList());
   TObject* obj = 0;
   
   while ((obj = next())!=0) {
      TDirectory* dir = dynamic_cast<TDirectory*> (obj);
      if (dir!=0)
         if (dir->GetSeekDir()==keyid) return dir;
   }
   
   return 0;
   
}

//______________________________________________________________________________
Int_t TXMLFile::DirReadKeys(TDirectory* dir)
{
   // Read keys for directory
   // Make sence only once, while next time no new subnodes will be created
   
   TKeyXML* key = FindDirKey(dir);
   if (key==0) return 0;
   
   return ReadKeysList(dir, key->KeyNode());
}

//______________________________________________________________________________
void TXMLFile::DirWriteKeys(TDirectory*)
{
   // Update key attributes

   TIter next(GetListOfKeys());
   TObject* obj = 0;
   
   while ((obj = next())!=0) {
      TKeyXML* key = dynamic_cast<TKeyXML*> (obj);
      if (key!=0) key->UpdateAttributes();
   }
}

//______________________________________________________________________________
void TXMLFile::DirWriteHeader(TDirectory* dir)
{
   //Write the directory header
   TKeyXML* key = FindDirKey(dir);
   if (key!=0)
      key->UpdateObject(dir);
}
 TXMLFile.cxx:1
 TXMLFile.cxx:2
 TXMLFile.cxx:3
 TXMLFile.cxx:4
 TXMLFile.cxx:5
 TXMLFile.cxx:6
 TXMLFile.cxx:7
 TXMLFile.cxx:8
 TXMLFile.cxx:9
 TXMLFile.cxx:10
 TXMLFile.cxx:11
 TXMLFile.cxx:12
 TXMLFile.cxx:13
 TXMLFile.cxx:14
 TXMLFile.cxx:15
 TXMLFile.cxx:16
 TXMLFile.cxx:17
 TXMLFile.cxx:18
 TXMLFile.cxx:19
 TXMLFile.cxx:20
 TXMLFile.cxx:21
 TXMLFile.cxx:22
 TXMLFile.cxx:23
 TXMLFile.cxx:24
 TXMLFile.cxx:25
 TXMLFile.cxx:26
 TXMLFile.cxx:27
 TXMLFile.cxx:28
 TXMLFile.cxx:29
 TXMLFile.cxx:30
 TXMLFile.cxx:31
 TXMLFile.cxx:32
 TXMLFile.cxx:33
 TXMLFile.cxx:34
 TXMLFile.cxx:35
 TXMLFile.cxx:36
 TXMLFile.cxx:37
 TXMLFile.cxx:38
 TXMLFile.cxx:39
 TXMLFile.cxx:40
 TXMLFile.cxx:41
 TXMLFile.cxx:42
 TXMLFile.cxx:43
 TXMLFile.cxx:44
 TXMLFile.cxx:45
 TXMLFile.cxx:46
 TXMLFile.cxx:47
 TXMLFile.cxx:48
 TXMLFile.cxx:49
 TXMLFile.cxx:50
 TXMLFile.cxx:51
 TXMLFile.cxx:52
 TXMLFile.cxx:53
 TXMLFile.cxx:54
 TXMLFile.cxx:55
 TXMLFile.cxx:56
 TXMLFile.cxx:57
 TXMLFile.cxx:58
 TXMLFile.cxx:59
 TXMLFile.cxx:60
 TXMLFile.cxx:61
 TXMLFile.cxx:62
 TXMLFile.cxx:63
 TXMLFile.cxx:64
 TXMLFile.cxx:65
 TXMLFile.cxx:66
 TXMLFile.cxx:67
 TXMLFile.cxx:68
 TXMLFile.cxx:69
 TXMLFile.cxx:70
 TXMLFile.cxx:71
 TXMLFile.cxx:72
 TXMLFile.cxx:73
 TXMLFile.cxx:74
 TXMLFile.cxx:75
 TXMLFile.cxx:76
 TXMLFile.cxx:77
 TXMLFile.cxx:78
 TXMLFile.cxx:79
 TXMLFile.cxx:80
 TXMLFile.cxx:81
 TXMLFile.cxx:82
 TXMLFile.cxx:83
 TXMLFile.cxx:84
 TXMLFile.cxx:85
 TXMLFile.cxx:86
 TXMLFile.cxx:87
 TXMLFile.cxx:88
 TXMLFile.cxx:89
 TXMLFile.cxx:90
 TXMLFile.cxx:91
 TXMLFile.cxx:92
 TXMLFile.cxx:93
 TXMLFile.cxx:94
 TXMLFile.cxx:95
 TXMLFile.cxx:96
 TXMLFile.cxx:97
 TXMLFile.cxx:98
 TXMLFile.cxx:99
 TXMLFile.cxx:100
 TXMLFile.cxx:101
 TXMLFile.cxx:102
 TXMLFile.cxx:103
 TXMLFile.cxx:104
 TXMLFile.cxx:105
 TXMLFile.cxx:106
 TXMLFile.cxx:107
 TXMLFile.cxx:108
 TXMLFile.cxx:109
 TXMLFile.cxx:110
 TXMLFile.cxx:111
 TXMLFile.cxx:112
 TXMLFile.cxx:113
 TXMLFile.cxx:114
 TXMLFile.cxx:115
 TXMLFile.cxx:116
 TXMLFile.cxx:117
 TXMLFile.cxx:118
 TXMLFile.cxx:119
 TXMLFile.cxx:120
 TXMLFile.cxx:121
 TXMLFile.cxx:122
 TXMLFile.cxx:123
 TXMLFile.cxx:124
 TXMLFile.cxx:125
 TXMLFile.cxx:126
 TXMLFile.cxx:127
 TXMLFile.cxx:128
 TXMLFile.cxx:129
 TXMLFile.cxx:130
 TXMLFile.cxx:131
 TXMLFile.cxx:132
 TXMLFile.cxx:133
 TXMLFile.cxx:134
 TXMLFile.cxx:135
 TXMLFile.cxx:136
 TXMLFile.cxx:137
 TXMLFile.cxx:138
 TXMLFile.cxx:139
 TXMLFile.cxx:140
 TXMLFile.cxx:141
 TXMLFile.cxx:142
 TXMLFile.cxx:143
 TXMLFile.cxx:144
 TXMLFile.cxx:145
 TXMLFile.cxx:146
 TXMLFile.cxx:147
 TXMLFile.cxx:148
 TXMLFile.cxx:149
 TXMLFile.cxx:150
 TXMLFile.cxx:151
 TXMLFile.cxx:152
 TXMLFile.cxx:153
 TXMLFile.cxx:154
 TXMLFile.cxx:155
 TXMLFile.cxx:156
 TXMLFile.cxx:157
 TXMLFile.cxx:158
 TXMLFile.cxx:159
 TXMLFile.cxx:160
 TXMLFile.cxx:161
 TXMLFile.cxx:162
 TXMLFile.cxx:163
 TXMLFile.cxx:164
 TXMLFile.cxx:165
 TXMLFile.cxx:166
 TXMLFile.cxx:167
 TXMLFile.cxx:168
 TXMLFile.cxx:169
 TXMLFile.cxx:170
 TXMLFile.cxx:171
 TXMLFile.cxx:172
 TXMLFile.cxx:173
 TXMLFile.cxx:174
 TXMLFile.cxx:175
 TXMLFile.cxx:176
 TXMLFile.cxx:177
 TXMLFile.cxx:178
 TXMLFile.cxx:179
 TXMLFile.cxx:180
 TXMLFile.cxx:181
 TXMLFile.cxx:182
 TXMLFile.cxx:183
 TXMLFile.cxx:184
 TXMLFile.cxx:185
 TXMLFile.cxx:186
 TXMLFile.cxx:187
 TXMLFile.cxx:188
 TXMLFile.cxx:189
 TXMLFile.cxx:190
 TXMLFile.cxx:191
 TXMLFile.cxx:192
 TXMLFile.cxx:193
 TXMLFile.cxx:194
 TXMLFile.cxx:195
 TXMLFile.cxx:196
 TXMLFile.cxx:197
 TXMLFile.cxx:198
 TXMLFile.cxx:199
 TXMLFile.cxx:200
 TXMLFile.cxx:201
 TXMLFile.cxx:202
 TXMLFile.cxx:203
 TXMLFile.cxx:204
 TXMLFile.cxx:205
 TXMLFile.cxx:206
 TXMLFile.cxx:207
 TXMLFile.cxx:208
 TXMLFile.cxx:209
 TXMLFile.cxx:210
 TXMLFile.cxx:211
 TXMLFile.cxx:212
 TXMLFile.cxx:213
 TXMLFile.cxx:214
 TXMLFile.cxx:215
 TXMLFile.cxx:216
 TXMLFile.cxx:217
 TXMLFile.cxx:218
 TXMLFile.cxx:219
 TXMLFile.cxx:220
 TXMLFile.cxx:221
 TXMLFile.cxx:222
 TXMLFile.cxx:223
 TXMLFile.cxx:224
 TXMLFile.cxx:225
 TXMLFile.cxx:226
 TXMLFile.cxx:227
 TXMLFile.cxx:228
 TXMLFile.cxx:229
 TXMLFile.cxx:230
 TXMLFile.cxx:231
 TXMLFile.cxx:232
 TXMLFile.cxx:233
 TXMLFile.cxx:234
 TXMLFile.cxx:235
 TXMLFile.cxx:236
 TXMLFile.cxx:237
 TXMLFile.cxx:238
 TXMLFile.cxx:239
 TXMLFile.cxx:240
 TXMLFile.cxx:241
 TXMLFile.cxx:242
 TXMLFile.cxx:243
 TXMLFile.cxx:244
 TXMLFile.cxx:245
 TXMLFile.cxx:246
 TXMLFile.cxx:247
 TXMLFile.cxx:248
 TXMLFile.cxx:249
 TXMLFile.cxx:250
 TXMLFile.cxx:251
 TXMLFile.cxx:252
 TXMLFile.cxx:253
 TXMLFile.cxx:254
 TXMLFile.cxx:255
 TXMLFile.cxx:256
 TXMLFile.cxx:257
 TXMLFile.cxx:258
 TXMLFile.cxx:259
 TXMLFile.cxx:260
 TXMLFile.cxx:261
 TXMLFile.cxx:262
 TXMLFile.cxx:263
 TXMLFile.cxx:264
 TXMLFile.cxx:265
 TXMLFile.cxx:266
 TXMLFile.cxx:267
 TXMLFile.cxx:268
 TXMLFile.cxx:269
 TXMLFile.cxx:270
 TXMLFile.cxx:271
 TXMLFile.cxx:272
 TXMLFile.cxx:273
 TXMLFile.cxx:274
 TXMLFile.cxx:275
 TXMLFile.cxx:276
 TXMLFile.cxx:277
 TXMLFile.cxx:278
 TXMLFile.cxx:279
 TXMLFile.cxx:280
 TXMLFile.cxx:281
 TXMLFile.cxx:282
 TXMLFile.cxx:283
 TXMLFile.cxx:284
 TXMLFile.cxx:285
 TXMLFile.cxx:286
 TXMLFile.cxx:287
 TXMLFile.cxx:288
 TXMLFile.cxx:289
 TXMLFile.cxx:290
 TXMLFile.cxx:291
 TXMLFile.cxx:292
 TXMLFile.cxx:293
 TXMLFile.cxx:294
 TXMLFile.cxx:295
 TXMLFile.cxx:296
 TXMLFile.cxx:297
 TXMLFile.cxx:298
 TXMLFile.cxx:299
 TXMLFile.cxx:300
 TXMLFile.cxx:301
 TXMLFile.cxx:302
 TXMLFile.cxx:303
 TXMLFile.cxx:304
 TXMLFile.cxx:305
 TXMLFile.cxx:306
 TXMLFile.cxx:307
 TXMLFile.cxx:308
 TXMLFile.cxx:309
 TXMLFile.cxx:310
 TXMLFile.cxx:311
 TXMLFile.cxx:312
 TXMLFile.cxx:313
 TXMLFile.cxx:314
 TXMLFile.cxx:315
 TXMLFile.cxx:316
 TXMLFile.cxx:317
 TXMLFile.cxx:318
 TXMLFile.cxx:319
 TXMLFile.cxx:320
 TXMLFile.cxx:321
 TXMLFile.cxx:322
 TXMLFile.cxx:323
 TXMLFile.cxx:324
 TXMLFile.cxx:325
 TXMLFile.cxx:326
 TXMLFile.cxx:327
 TXMLFile.cxx:328
 TXMLFile.cxx:329
 TXMLFile.cxx:330
 TXMLFile.cxx:331
 TXMLFile.cxx:332
 TXMLFile.cxx:333
 TXMLFile.cxx:334
 TXMLFile.cxx:335
 TXMLFile.cxx:336
 TXMLFile.cxx:337
 TXMLFile.cxx:338
 TXMLFile.cxx:339
 TXMLFile.cxx:340
 TXMLFile.cxx:341
 TXMLFile.cxx:342
 TXMLFile.cxx:343
 TXMLFile.cxx:344
 TXMLFile.cxx:345
 TXMLFile.cxx:346
 TXMLFile.cxx:347
 TXMLFile.cxx:348
 TXMLFile.cxx:349
 TXMLFile.cxx:350
 TXMLFile.cxx:351
 TXMLFile.cxx:352
 TXMLFile.cxx:353
 TXMLFile.cxx:354
 TXMLFile.cxx:355
 TXMLFile.cxx:356
 TXMLFile.cxx:357
 TXMLFile.cxx:358
 TXMLFile.cxx:359
 TXMLFile.cxx:360
 TXMLFile.cxx:361
 TXMLFile.cxx:362
 TXMLFile.cxx:363
 TXMLFile.cxx:364
 TXMLFile.cxx:365
 TXMLFile.cxx:366
 TXMLFile.cxx:367
 TXMLFile.cxx:368
 TXMLFile.cxx:369
 TXMLFile.cxx:370
 TXMLFile.cxx:371
 TXMLFile.cxx:372
 TXMLFile.cxx:373
 TXMLFile.cxx:374
 TXMLFile.cxx:375
 TXMLFile.cxx:376
 TXMLFile.cxx:377
 TXMLFile.cxx:378
 TXMLFile.cxx:379
 TXMLFile.cxx:380
 TXMLFile.cxx:381
 TXMLFile.cxx:382
 TXMLFile.cxx:383
 TXMLFile.cxx:384
 TXMLFile.cxx:385
 TXMLFile.cxx:386
 TXMLFile.cxx:387
 TXMLFile.cxx:388
 TXMLFile.cxx:389
 TXMLFile.cxx:390
 TXMLFile.cxx:391
 TXMLFile.cxx:392
 TXMLFile.cxx:393
 TXMLFile.cxx:394
 TXMLFile.cxx:395
 TXMLFile.cxx:396
 TXMLFile.cxx:397
 TXMLFile.cxx:398
 TXMLFile.cxx:399
 TXMLFile.cxx:400
 TXMLFile.cxx:401
 TXMLFile.cxx:402
 TXMLFile.cxx:403
 TXMLFile.cxx:404
 TXMLFile.cxx:405
 TXMLFile.cxx:406
 TXMLFile.cxx:407
 TXMLFile.cxx:408
 TXMLFile.cxx:409
 TXMLFile.cxx:410
 TXMLFile.cxx:411
 TXMLFile.cxx:412
 TXMLFile.cxx:413
 TXMLFile.cxx:414
 TXMLFile.cxx:415
 TXMLFile.cxx:416
 TXMLFile.cxx:417
 TXMLFile.cxx:418
 TXMLFile.cxx:419
 TXMLFile.cxx:420
 TXMLFile.cxx:421
 TXMLFile.cxx:422
 TXMLFile.cxx:423
 TXMLFile.cxx:424
 TXMLFile.cxx:425
 TXMLFile.cxx:426
 TXMLFile.cxx:427
 TXMLFile.cxx:428
 TXMLFile.cxx:429
 TXMLFile.cxx:430
 TXMLFile.cxx:431
 TXMLFile.cxx:432
 TXMLFile.cxx:433
 TXMLFile.cxx:434
 TXMLFile.cxx:435
 TXMLFile.cxx:436
 TXMLFile.cxx:437
 TXMLFile.cxx:438
 TXMLFile.cxx:439
 TXMLFile.cxx:440
 TXMLFile.cxx:441
 TXMLFile.cxx:442
 TXMLFile.cxx:443
 TXMLFile.cxx:444
 TXMLFile.cxx:445
 TXMLFile.cxx:446
 TXMLFile.cxx:447
 TXMLFile.cxx:448
 TXMLFile.cxx:449
 TXMLFile.cxx:450
 TXMLFile.cxx:451
 TXMLFile.cxx:452
 TXMLFile.cxx:453
 TXMLFile.cxx:454
 TXMLFile.cxx:455
 TXMLFile.cxx:456
 TXMLFile.cxx:457
 TXMLFile.cxx:458
 TXMLFile.cxx:459
 TXMLFile.cxx:460
 TXMLFile.cxx:461
 TXMLFile.cxx:462
 TXMLFile.cxx:463
 TXMLFile.cxx:464
 TXMLFile.cxx:465
 TXMLFile.cxx:466
 TXMLFile.cxx:467
 TXMLFile.cxx:468
 TXMLFile.cxx:469
 TXMLFile.cxx:470
 TXMLFile.cxx:471
 TXMLFile.cxx:472
 TXMLFile.cxx:473
 TXMLFile.cxx:474
 TXMLFile.cxx:475
 TXMLFile.cxx:476
 TXMLFile.cxx:477
 TXMLFile.cxx:478
 TXMLFile.cxx:479
 TXMLFile.cxx:480
 TXMLFile.cxx:481
 TXMLFile.cxx:482
 TXMLFile.cxx:483
 TXMLFile.cxx:484
 TXMLFile.cxx:485
 TXMLFile.cxx:486
 TXMLFile.cxx:487
 TXMLFile.cxx:488
 TXMLFile.cxx:489
 TXMLFile.cxx:490
 TXMLFile.cxx:491
 TXMLFile.cxx:492
 TXMLFile.cxx:493
 TXMLFile.cxx:494
 TXMLFile.cxx:495
 TXMLFile.cxx:496
 TXMLFile.cxx:497
 TXMLFile.cxx:498
 TXMLFile.cxx:499
 TXMLFile.cxx:500
 TXMLFile.cxx:501
 TXMLFile.cxx:502
 TXMLFile.cxx:503
 TXMLFile.cxx:504
 TXMLFile.cxx:505
 TXMLFile.cxx:506
 TXMLFile.cxx:507
 TXMLFile.cxx:508
 TXMLFile.cxx:509
 TXMLFile.cxx:510
 TXMLFile.cxx:511
 TXMLFile.cxx:512
 TXMLFile.cxx:513
 TXMLFile.cxx:514
 TXMLFile.cxx:515
 TXMLFile.cxx:516
 TXMLFile.cxx:517
 TXMLFile.cxx:518
 TXMLFile.cxx:519
 TXMLFile.cxx:520
 TXMLFile.cxx:521
 TXMLFile.cxx:522
 TXMLFile.cxx:523
 TXMLFile.cxx:524
 TXMLFile.cxx:525
 TXMLFile.cxx:526
 TXMLFile.cxx:527
 TXMLFile.cxx:528
 TXMLFile.cxx:529
 TXMLFile.cxx:530
 TXMLFile.cxx:531
 TXMLFile.cxx:532
 TXMLFile.cxx:533
 TXMLFile.cxx:534
 TXMLFile.cxx:535
 TXMLFile.cxx:536
 TXMLFile.cxx:537
 TXMLFile.cxx:538
 TXMLFile.cxx:539
 TXMLFile.cxx:540
 TXMLFile.cxx:541
 TXMLFile.cxx:542
 TXMLFile.cxx:543
 TXMLFile.cxx:544
 TXMLFile.cxx:545
 TXMLFile.cxx:546
 TXMLFile.cxx:547
 TXMLFile.cxx:548
 TXMLFile.cxx:549
 TXMLFile.cxx:550
 TXMLFile.cxx:551
 TXMLFile.cxx:552
 TXMLFile.cxx:553
 TXMLFile.cxx:554
 TXMLFile.cxx:555
 TXMLFile.cxx:556
 TXMLFile.cxx:557
 TXMLFile.cxx:558
 TXMLFile.cxx:559
 TXMLFile.cxx:560
 TXMLFile.cxx:561
 TXMLFile.cxx:562
 TXMLFile.cxx:563
 TXMLFile.cxx:564
 TXMLFile.cxx:565
 TXMLFile.cxx:566
 TXMLFile.cxx:567
 TXMLFile.cxx:568
 TXMLFile.cxx:569
 TXMLFile.cxx:570
 TXMLFile.cxx:571
 TXMLFile.cxx:572
 TXMLFile.cxx:573
 TXMLFile.cxx:574
 TXMLFile.cxx:575
 TXMLFile.cxx:576
 TXMLFile.cxx:577
 TXMLFile.cxx:578
 TXMLFile.cxx:579
 TXMLFile.cxx:580
 TXMLFile.cxx:581
 TXMLFile.cxx:582
 TXMLFile.cxx:583
 TXMLFile.cxx:584
 TXMLFile.cxx:585
 TXMLFile.cxx:586
 TXMLFile.cxx:587
 TXMLFile.cxx:588
 TXMLFile.cxx:589
 TXMLFile.cxx:590
 TXMLFile.cxx:591
 TXMLFile.cxx:592
 TXMLFile.cxx:593
 TXMLFile.cxx:594
 TXMLFile.cxx:595
 TXMLFile.cxx:596
 TXMLFile.cxx:597
 TXMLFile.cxx:598
 TXMLFile.cxx:599
 TXMLFile.cxx:600
 TXMLFile.cxx:601
 TXMLFile.cxx:602
 TXMLFile.cxx:603
 TXMLFile.cxx:604
 TXMLFile.cxx:605
 TXMLFile.cxx:606
 TXMLFile.cxx:607
 TXMLFile.cxx:608
 TXMLFile.cxx:609
 TXMLFile.cxx:610
 TXMLFile.cxx:611
 TXMLFile.cxx:612
 TXMLFile.cxx:613
 TXMLFile.cxx:614
 TXMLFile.cxx:615
 TXMLFile.cxx:616
 TXMLFile.cxx:617
 TXMLFile.cxx:618
 TXMLFile.cxx:619
 TXMLFile.cxx:620
 TXMLFile.cxx:621
 TXMLFile.cxx:622
 TXMLFile.cxx:623
 TXMLFile.cxx:624
 TXMLFile.cxx:625
 TXMLFile.cxx:626
 TXMLFile.cxx:627
 TXMLFile.cxx:628
 TXMLFile.cxx:629
 TXMLFile.cxx:630
 TXMLFile.cxx:631
 TXMLFile.cxx:632
 TXMLFile.cxx:633
 TXMLFile.cxx:634
 TXMLFile.cxx:635
 TXMLFile.cxx:636
 TXMLFile.cxx:637
 TXMLFile.cxx:638
 TXMLFile.cxx:639
 TXMLFile.cxx:640
 TXMLFile.cxx:641
 TXMLFile.cxx:642
 TXMLFile.cxx:643
 TXMLFile.cxx:644
 TXMLFile.cxx:645
 TXMLFile.cxx:646
 TXMLFile.cxx:647
 TXMLFile.cxx:648
 TXMLFile.cxx:649
 TXMLFile.cxx:650
 TXMLFile.cxx:651
 TXMLFile.cxx:652
 TXMLFile.cxx:653
 TXMLFile.cxx:654
 TXMLFile.cxx:655
 TXMLFile.cxx:656
 TXMLFile.cxx:657
 TXMLFile.cxx:658
 TXMLFile.cxx:659
 TXMLFile.cxx:660
 TXMLFile.cxx:661
 TXMLFile.cxx:662
 TXMLFile.cxx:663
 TXMLFile.cxx:664
 TXMLFile.cxx:665
 TXMLFile.cxx:666
 TXMLFile.cxx:667
 TXMLFile.cxx:668
 TXMLFile.cxx:669
 TXMLFile.cxx:670
 TXMLFile.cxx:671
 TXMLFile.cxx:672
 TXMLFile.cxx:673
 TXMLFile.cxx:674
 TXMLFile.cxx:675
 TXMLFile.cxx:676
 TXMLFile.cxx:677
 TXMLFile.cxx:678
 TXMLFile.cxx:679
 TXMLFile.cxx:680
 TXMLFile.cxx:681
 TXMLFile.cxx:682
 TXMLFile.cxx:683
 TXMLFile.cxx:684
 TXMLFile.cxx:685
 TXMLFile.cxx:686
 TXMLFile.cxx:687
 TXMLFile.cxx:688
 TXMLFile.cxx:689
 TXMLFile.cxx:690
 TXMLFile.cxx:691
 TXMLFile.cxx:692
 TXMLFile.cxx:693
 TXMLFile.cxx:694
 TXMLFile.cxx:695
 TXMLFile.cxx:696
 TXMLFile.cxx:697
 TXMLFile.cxx:698
 TXMLFile.cxx:699
 TXMLFile.cxx:700
 TXMLFile.cxx:701
 TXMLFile.cxx:702
 TXMLFile.cxx:703
 TXMLFile.cxx:704
 TXMLFile.cxx:705
 TXMLFile.cxx:706
 TXMLFile.cxx:707
 TXMLFile.cxx:708
 TXMLFile.cxx:709
 TXMLFile.cxx:710
 TXMLFile.cxx:711
 TXMLFile.cxx:712
 TXMLFile.cxx:713
 TXMLFile.cxx:714
 TXMLFile.cxx:715
 TXMLFile.cxx:716
 TXMLFile.cxx:717
 TXMLFile.cxx:718
 TXMLFile.cxx:719
 TXMLFile.cxx:720
 TXMLFile.cxx:721
 TXMLFile.cxx:722
 TXMLFile.cxx:723
 TXMLFile.cxx:724
 TXMLFile.cxx:725
 TXMLFile.cxx:726
 TXMLFile.cxx:727
 TXMLFile.cxx:728
 TXMLFile.cxx:729
 TXMLFile.cxx:730
 TXMLFile.cxx:731
 TXMLFile.cxx:732
 TXMLFile.cxx:733
 TXMLFile.cxx:734
 TXMLFile.cxx:735
 TXMLFile.cxx:736
 TXMLFile.cxx:737
 TXMLFile.cxx:738
 TXMLFile.cxx:739
 TXMLFile.cxx:740
 TXMLFile.cxx:741
 TXMLFile.cxx:742
 TXMLFile.cxx:743
 TXMLFile.cxx:744
 TXMLFile.cxx:745
 TXMLFile.cxx:746
 TXMLFile.cxx:747
 TXMLFile.cxx:748
 TXMLFile.cxx:749
 TXMLFile.cxx:750
 TXMLFile.cxx:751
 TXMLFile.cxx:752
 TXMLFile.cxx:753
 TXMLFile.cxx:754
 TXMLFile.cxx:755
 TXMLFile.cxx:756
 TXMLFile.cxx:757
 TXMLFile.cxx:758
 TXMLFile.cxx:759
 TXMLFile.cxx:760
 TXMLFile.cxx:761
 TXMLFile.cxx:762
 TXMLFile.cxx:763
 TXMLFile.cxx:764
 TXMLFile.cxx:765
 TXMLFile.cxx:766
 TXMLFile.cxx:767
 TXMLFile.cxx:768
 TXMLFile.cxx:769
 TXMLFile.cxx:770
 TXMLFile.cxx:771
 TXMLFile.cxx:772
 TXMLFile.cxx:773
 TXMLFile.cxx:774
 TXMLFile.cxx:775
 TXMLFile.cxx:776
 TXMLFile.cxx:777
 TXMLFile.cxx:778
 TXMLFile.cxx:779
 TXMLFile.cxx:780
 TXMLFile.cxx:781
 TXMLFile.cxx:782
 TXMLFile.cxx:783
 TXMLFile.cxx:784
 TXMLFile.cxx:785
 TXMLFile.cxx:786
 TXMLFile.cxx:787
 TXMLFile.cxx:788
 TXMLFile.cxx:789
 TXMLFile.cxx:790
 TXMLFile.cxx:791
 TXMLFile.cxx:792
 TXMLFile.cxx:793
 TXMLFile.cxx:794
 TXMLFile.cxx:795
 TXMLFile.cxx:796
 TXMLFile.cxx:797
 TXMLFile.cxx:798
 TXMLFile.cxx:799
 TXMLFile.cxx:800
 TXMLFile.cxx:801
 TXMLFile.cxx:802
 TXMLFile.cxx:803
 TXMLFile.cxx:804
 TXMLFile.cxx:805
 TXMLFile.cxx:806
 TXMLFile.cxx:807
 TXMLFile.cxx:808
 TXMLFile.cxx:809
 TXMLFile.cxx:810
 TXMLFile.cxx:811
 TXMLFile.cxx:812
 TXMLFile.cxx:813
 TXMLFile.cxx:814
 TXMLFile.cxx:815
 TXMLFile.cxx:816
 TXMLFile.cxx:817
 TXMLFile.cxx:818
 TXMLFile.cxx:819
 TXMLFile.cxx:820
 TXMLFile.cxx:821
 TXMLFile.cxx:822
 TXMLFile.cxx:823
 TXMLFile.cxx:824
 TXMLFile.cxx:825
 TXMLFile.cxx:826
 TXMLFile.cxx:827
 TXMLFile.cxx:828
 TXMLFile.cxx:829
 TXMLFile.cxx:830
 TXMLFile.cxx:831
 TXMLFile.cxx:832
 TXMLFile.cxx:833
 TXMLFile.cxx:834
 TXMLFile.cxx:835
 TXMLFile.cxx:836
 TXMLFile.cxx:837
 TXMLFile.cxx:838
 TXMLFile.cxx:839
 TXMLFile.cxx:840
 TXMLFile.cxx:841
 TXMLFile.cxx:842
 TXMLFile.cxx:843
 TXMLFile.cxx:844
 TXMLFile.cxx:845
 TXMLFile.cxx:846
 TXMLFile.cxx:847
 TXMLFile.cxx:848
 TXMLFile.cxx:849
 TXMLFile.cxx:850
 TXMLFile.cxx:851
 TXMLFile.cxx:852
 TXMLFile.cxx:853
 TXMLFile.cxx:854
 TXMLFile.cxx:855
 TXMLFile.cxx:856
 TXMLFile.cxx:857
 TXMLFile.cxx:858
 TXMLFile.cxx:859
 TXMLFile.cxx:860
 TXMLFile.cxx:861
 TXMLFile.cxx:862
 TXMLFile.cxx:863
 TXMLFile.cxx:864
 TXMLFile.cxx:865
 TXMLFile.cxx:866
 TXMLFile.cxx:867
 TXMLFile.cxx:868
 TXMLFile.cxx:869
 TXMLFile.cxx:870
 TXMLFile.cxx:871
 TXMLFile.cxx:872
 TXMLFile.cxx:873
 TXMLFile.cxx:874
 TXMLFile.cxx:875
 TXMLFile.cxx:876
 TXMLFile.cxx:877
 TXMLFile.cxx:878
 TXMLFile.cxx:879
 TXMLFile.cxx:880
 TXMLFile.cxx:881
 TXMLFile.cxx:882
 TXMLFile.cxx:883
 TXMLFile.cxx:884
 TXMLFile.cxx:885
 TXMLFile.cxx:886
 TXMLFile.cxx:887
 TXMLFile.cxx:888
 TXMLFile.cxx:889
 TXMLFile.cxx:890
 TXMLFile.cxx:891
 TXMLFile.cxx:892
 TXMLFile.cxx:893
 TXMLFile.cxx:894
 TXMLFile.cxx:895
 TXMLFile.cxx:896
 TXMLFile.cxx:897
 TXMLFile.cxx:898
 TXMLFile.cxx:899
 TXMLFile.cxx:900
 TXMLFile.cxx:901
 TXMLFile.cxx:902
 TXMLFile.cxx:903
 TXMLFile.cxx:904
 TXMLFile.cxx:905
 TXMLFile.cxx:906
 TXMLFile.cxx:907
 TXMLFile.cxx:908
 TXMLFile.cxx:909
 TXMLFile.cxx:910
 TXMLFile.cxx:911
 TXMLFile.cxx:912
 TXMLFile.cxx:913
 TXMLFile.cxx:914
 TXMLFile.cxx:915
 TXMLFile.cxx:916
 TXMLFile.cxx:917
 TXMLFile.cxx:918
 TXMLFile.cxx:919
 TXMLFile.cxx:920
 TXMLFile.cxx:921
 TXMLFile.cxx:922
 TXMLFile.cxx:923
 TXMLFile.cxx:924
 TXMLFile.cxx:925
 TXMLFile.cxx:926
 TXMLFile.cxx:927
 TXMLFile.cxx:928
 TXMLFile.cxx:929
 TXMLFile.cxx:930
 TXMLFile.cxx:931
 TXMLFile.cxx:932
 TXMLFile.cxx:933
 TXMLFile.cxx:934
 TXMLFile.cxx:935
 TXMLFile.cxx:936
 TXMLFile.cxx:937
 TXMLFile.cxx:938
 TXMLFile.cxx:939
 TXMLFile.cxx:940
 TXMLFile.cxx:941
 TXMLFile.cxx:942
 TXMLFile.cxx:943
 TXMLFile.cxx:944
 TXMLFile.cxx:945
 TXMLFile.cxx:946
 TXMLFile.cxx:947
 TXMLFile.cxx:948
 TXMLFile.cxx:949
 TXMLFile.cxx:950
 TXMLFile.cxx:951
 TXMLFile.cxx:952
 TXMLFile.cxx:953
 TXMLFile.cxx:954
 TXMLFile.cxx:955
 TXMLFile.cxx:956
 TXMLFile.cxx:957
 TXMLFile.cxx:958
 TXMLFile.cxx:959
 TXMLFile.cxx:960
 TXMLFile.cxx:961
 TXMLFile.cxx:962
 TXMLFile.cxx:963
 TXMLFile.cxx:964
 TXMLFile.cxx:965
 TXMLFile.cxx:966
 TXMLFile.cxx:967
 TXMLFile.cxx:968
 TXMLFile.cxx:969
 TXMLFile.cxx:970
 TXMLFile.cxx:971
 TXMLFile.cxx:972
 TXMLFile.cxx:973
 TXMLFile.cxx:974
 TXMLFile.cxx:975
 TXMLFile.cxx:976
 TXMLFile.cxx:977
 TXMLFile.cxx:978
 TXMLFile.cxx:979
 TXMLFile.cxx:980
 TXMLFile.cxx:981
 TXMLFile.cxx:982
 TXMLFile.cxx:983
 TXMLFile.cxx:984
 TXMLFile.cxx:985
 TXMLFile.cxx:986
 TXMLFile.cxx:987
 TXMLFile.cxx:988
 TXMLFile.cxx:989
 TXMLFile.cxx:990
 TXMLFile.cxx:991
 TXMLFile.cxx:992
 TXMLFile.cxx:993
 TXMLFile.cxx:994
 TXMLFile.cxx:995
 TXMLFile.cxx:996
 TXMLFile.cxx:997
 TXMLFile.cxx:998
 TXMLFile.cxx:999
 TXMLFile.cxx:1000
 TXMLFile.cxx:1001
 TXMLFile.cxx:1002
 TXMLFile.cxx:1003
 TXMLFile.cxx:1004
 TXMLFile.cxx:1005
 TXMLFile.cxx:1006
 TXMLFile.cxx:1007
 TXMLFile.cxx:1008
 TXMLFile.cxx:1009
 TXMLFile.cxx:1010
 TXMLFile.cxx:1011
 TXMLFile.cxx:1012
 TXMLFile.cxx:1013
 TXMLFile.cxx:1014
 TXMLFile.cxx:1015
 TXMLFile.cxx:1016
 TXMLFile.cxx:1017
 TXMLFile.cxx:1018
 TXMLFile.cxx:1019
 TXMLFile.cxx:1020
 TXMLFile.cxx:1021
 TXMLFile.cxx:1022
 TXMLFile.cxx:1023
 TXMLFile.cxx:1024
 TXMLFile.cxx:1025
 TXMLFile.cxx:1026
 TXMLFile.cxx:1027
 TXMLFile.cxx:1028
 TXMLFile.cxx:1029
 TXMLFile.cxx:1030
 TXMLFile.cxx:1031
 TXMLFile.cxx:1032
 TXMLFile.cxx:1033
 TXMLFile.cxx:1034
 TXMLFile.cxx:1035
 TXMLFile.cxx:1036
 TXMLFile.cxx:1037
 TXMLFile.cxx:1038
 TXMLFile.cxx:1039
 TXMLFile.cxx:1040
 TXMLFile.cxx:1041
 TXMLFile.cxx:1042
 TXMLFile.cxx:1043
 TXMLFile.cxx:1044
 TXMLFile.cxx:1045
 TXMLFile.cxx:1046
 TXMLFile.cxx:1047
 TXMLFile.cxx:1048
 TXMLFile.cxx:1049
 TXMLFile.cxx:1050
 TXMLFile.cxx:1051
 TXMLFile.cxx:1052
 TXMLFile.cxx:1053
 TXMLFile.cxx:1054
 TXMLFile.cxx:1055
 TXMLFile.cxx:1056
 TXMLFile.cxx:1057
 TXMLFile.cxx:1058
 TXMLFile.cxx:1059
 TXMLFile.cxx:1060
 TXMLFile.cxx:1061
 TXMLFile.cxx:1062
 TXMLFile.cxx:1063
 TXMLFile.cxx:1064
 TXMLFile.cxx:1065
 TXMLFile.cxx:1066
 TXMLFile.cxx:1067
 TXMLFile.cxx:1068
 TXMLFile.cxx:1069
 TXMLFile.cxx:1070
 TXMLFile.cxx:1071
 TXMLFile.cxx:1072
 TXMLFile.cxx:1073
 TXMLFile.cxx:1074
 TXMLFile.cxx:1075
 TXMLFile.cxx:1076
 TXMLFile.cxx:1077
 TXMLFile.cxx:1078
 TXMLFile.cxx:1079
 TXMLFile.cxx:1080
 TXMLFile.cxx:1081
 TXMLFile.cxx:1082
 TXMLFile.cxx:1083
 TXMLFile.cxx:1084
 TXMLFile.cxx:1085
 TXMLFile.cxx:1086
 TXMLFile.cxx:1087
 TXMLFile.cxx:1088
 TXMLFile.cxx:1089
 TXMLFile.cxx:1090
 TXMLFile.cxx:1091
 TXMLFile.cxx:1092
 TXMLFile.cxx:1093
 TXMLFile.cxx:1094
 TXMLFile.cxx:1095
 TXMLFile.cxx:1096
 TXMLFile.cxx:1097
 TXMLFile.cxx:1098
 TXMLFile.cxx:1099
 TXMLFile.cxx:1100
 TXMLFile.cxx:1101
 TXMLFile.cxx:1102
 TXMLFile.cxx:1103
 TXMLFile.cxx:1104
 TXMLFile.cxx:1105
 TXMLFile.cxx:1106
 TXMLFile.cxx:1107