#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)
{
   
   
   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)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   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();  
   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;
   }
   
   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)
{
   
   
   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)
{
   
   
   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;
   }
   
   TDirectoryFile::Close();
   cd();      
   if (cursav)
      cursav->cd();
   else {
      gFile      = 0;
      gDirectory = gROOT;
   }
   
   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()
{
   
   Close();
   if (fXML!=0) {
      delete fXML;
      fXML = 0;
   }
}
void TXMLFile::operator=(const TXMLFile &)
{
   
}
Bool_t TXMLFile::IsOpen() const
{
   
   return fDoc != 0;
}
Int_t TXMLFile::ReOpen(Option_t* mode)
{
   
   
   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") {
      
      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)
{
   
   return new TKeyXML(mother, ++fKeyCounter, obj, name);
}
TKey* TXMLFile::CreateKey(TDirectory* mother, const void* obj, const TClass* cl, const char* name, Int_t)
{
   
   return new TKeyXML(mother, ++fKeyCounter, obj, cl, name);
}
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;
   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);
      
   CombineNodesTree(this, fRootNode, kTRUE);
   WriteStreamerInfo();
   if (fStreamerInfoNode)
      fXML->AddChild(fRootNode, fStreamerInfoNode);
   Int_t layout = GetCompressionLevel()>5 ? 0 : 1;
   fXML->SaveDoc(fDoc, fname, layout);
   CombineNodesTree(this, fRootNode, kFALSE);
   if (fStreamerInfoNode)
      fXML->UnlinkNode(fStreamerInfoNode);
}
void TXMLFile::CombineNodesTree(TDirectory* dir, XMLNodePointer_t topnode, Bool_t dolink)
{
   
   
   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()
{
   
   
   
   
   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)
{
   
   
   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()
{
   
   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++) {
      TStreamerInfo* 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 iter(info->GetElements());
      TStreamerElement* elem=0;
      while ((elem= (TStreamerElement*) iter()) != 0) {
         StoreStreamerElement(infonode, elem);
      }
   }
}
TList* TXMLFile::GetStreamerInfoList()
{
   
   
   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), 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)
{
   
   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)
{
  
   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)
{
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   if (IsWritable() && (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetXmlLayout(layout);
}
void TXMLFile::SetStoreStreamerInfos(Bool_t iConvert)
{
   
   
   
   
   if (IsWritable() &&  (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetStoreStreamerInfos(iConvert);
}
void TXMLFile::SetUsedDtd(Bool_t use)
{
   
   
   
   if (IsWritable() &&  (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetUsedDtd(use);
}
void TXMLFile::SetUseNamespaces(Bool_t iUseNamespaces)
{
   
   
   
   
   
   
   
   
   
   
   
   
   if (IsWritable() && (GetListOfKeys()->GetSize()==0))
      TXMLSetup::SetUseNamespaces(iUseNamespaces);
}
Bool_t TXMLFile::AddXmlComment(const char* comment)
{
   
   
   
   
   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)
{
   
   
   
   
   
   
   
   
   if (!IsWritable() || (fXML==0)) return kFALSE;
    
   return fXML->AddDocStyleSheet(fDoc, href,type,title,alternate,media,charset);
}                                  
Bool_t TXMLFile::AddXmlLine(const char* line)
{
   
   
   
   
   
   
   if (!IsWritable() || (fXML==0)) return kFALSE;
   return fXML->AddDocRawLine(fDoc, line); 
}
Long64_t TXMLFile::DirCreateEntry(TDirectory* dir)
{
   
   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)
{
   
   
   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)
{
   
   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)
{
   
   
   
   TKeyXML* key = FindDirKey(dir);
   if (key==0) return 0;
   
   return ReadKeysList(dir, key->KeyNode());
}
void TXMLFile::DirWriteKeys(TDirectory*)
{
   
   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)
{
   
   TKeyXML* key = FindDirKey(dir);
   if (key!=0)
      key->UpdateObject(dir);
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.