// @(#)root/xml:$Name:  $:$Id: TXMLSetup.cxx,v 1.6 2004/06/29 14:45:38 brun Exp $
// Author: Sergey Linev  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.             *
 *************************************************************************/

//________________________________________________________________________
//
// Class TXMLSetup is used as storage of settings, relevant for storing data
// in xml file. This class is used in TXMLFile and in TXmlBuffer classes.
// Xml settings can be codded via a string in following format
//
//   "2xoo"
//    ||| \ .
//    || \ usage of name spaces.
//    | \ usage of DTD;
//     \ storage of TStreamerInfo objects in file;
//      layout of xml file (= 2 - specialized (default), = 3 - generic) 
//
// For last three boolean parameters "x" means true, "o" - false
//
// Such string can be set as argument of TXMLFile constructor. In that
// case new TXMLFile with such parameters will be created. 
// These settings automatically stored in xml file.

//________________________________________________________________________



#include "TXMLSetup.h"

#include "TROOT.h"
#include "TClass.h"
#include "TStreamerElement.h"
#include "Riostream.h"

ClassImp(TXMLSetup);

const char* xmlNames_Root        = "root";
const char* xmlNames_Setup       = "setup";
const char* xmlNames_ClassVersion= "version";
const char* xmlNames_OnlyVersion = "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_ObjClass    = "class";
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_v           = "v";
const char* xmlNames_cnt         = "cnt";
const char* xmlNames_true        = "true";
const char* xmlNames_false       = "false";
const char* xmlNames_SInfos      = "StreamerInfos";

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";


TString TXMLSetup::fNameSpaceBase = "http://root.cern.ch/root/htmldoc/";   

//______________________________________________________________________________
TString TXMLSetup::DefaultXmlSetup() 
{
  return TString("2xoo");    
}

//______________________________________________________________________________
void TXMLSetup::SetNameSpaceBase(const char* namespacebase) {
   fNameSpaceBase = namespacebase; 
}

//______________________________________________________________________________
TXMLSetup::TXMLSetup() :
   fXmlLayout(kSpecialized),
   fStoreStreamerInfos(kTRUE),
   fUseDtd(kFALSE),
   fUseNamespaces(kFALSE),
   fRefCounter(0)
{
}

//______________________________________________________________________________
TXMLSetup::TXMLSetup(const char* opt) : fRefCounter(0)
{
   ReadSetupFromStr(opt);
}


//______________________________________________________________________________
TXMLSetup::TXMLSetup(const TXMLSetup& src) :
   fXmlLayout(src.fXmlLayout),
   fStoreStreamerInfos(src.fStoreStreamerInfos),
   fUseDtd(src.fUseDtd),
   fUseNamespaces(src.fUseNamespaces),
   fRefCounter(0)
{
}

//______________________________________________________________________________
TXMLSetup::~TXMLSetup()
{
}

//______________________________________________________________________________
TString TXMLSetup::GetSetupAsString() {
   char setupstr[10] = "2xxx";

   setupstr[0] = char(48+fXmlLayout);
   setupstr[1] = fStoreStreamerInfos ? 'x' : 'o';
   setupstr[2] = fUseDtd ? 'x' : 'o';
   setupstr[3] = fUseNamespaces ? 'x' : 'o';
  
   return TString(setupstr); 
}

//______________________________________________________________________________
Bool_t TXMLSetup::IsValidXmlSetup(const char* setupstr) 
{
   if ((setupstr==0) || (strlen(setupstr)!=4)) return kFALSE;
   TString str = setupstr;
   str.ToLower();
   if ((str[0]<48) || (str[0]>53)) return kFALSE;
   for (int n=1;n<4;n++)
     if ((str[n]!='o') && (str[n]!='x')) return kFALSE;
   return kTRUE;  
}


//______________________________________________________________________________
Bool_t TXMLSetup::ReadSetupFromStr(const char* setupstr)
{
   if ((setupstr==0) || (strlen(setupstr)<4)) return kFALSE;
   Int_t lay          = EXMLLayout(setupstr[0] - 48);
   if (lay==kGeneralized) fXmlLayout = kGeneralized;
                     else fXmlLayout = kSpecialized;

   fStoreStreamerInfos = setupstr[1]=='x';
   fUseDtd            = kFALSE;
   fUseNamespaces     = setupstr[3]=='x';
   return kTRUE;
}

//______________________________________________________________________________
void TXMLSetup::PrintSetup()
{
   cout << " *** Setup printout ***" << endl;
   cout << "Attribute mode = " << fXmlLayout << endl;
   cout << "Store streamer infos = " << (fStoreStreamerInfos ? "true" : "false") << endl;
   cout << "Use dtd = " << (fUseDtd ? "true" : "false") << endl;
   cout << "Use name spaces = " << (fUseNamespaces ? "true" : "false") << endl;
}

//______________________________________________________________________________
const char* TXMLSetup::XmlConvertClassName(const char* clname)
{
   fStrBuf = clname;
   fStrBuf.ReplaceAll("<","_");
   fStrBuf.ReplaceAll(">","_");
   fStrBuf.ReplaceAll(",","_");
   fStrBuf.ReplaceAll(" ","_");
   return fStrBuf.Data();
}

//______________________________________________________________________________
const char* TXMLSetup::XmlClassNameSpaceRef(const TClass* cl)
{
   TString clname = XmlConvertClassName(cl->GetName());
   fStrBuf = fNameSpaceBase;
   fStrBuf += clname;
   if (fNameSpaceBase == "http://root.cern.ch/root/htmldoc/")
     fStrBuf += ".html";
   return fStrBuf.Data();
}

//______________________________________________________________________________
const char* TXMLSetup::XmlGetElementName(const TStreamerElement* el)
{
   if (el==0) return 0;
   if (!el->InheritsFrom(TStreamerSTL::Class())) return el->GetName();
   if (strcmp(el->GetName(), el->GetClassPointer()->GetName())!=0) return el->GetName();
   return XmlConvertClassName(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->GetName());
      if (strcmp(xmlClassName,name)==0) return cl;
   }
   return 0;
}

//______________________________________________________________________________
Int_t TXMLSetup::AtoI(const char* sbuf, Int_t def, const char* errinfo) 
{
   if (sbuf!=0) return atoi(sbuf);
   if (errinfo) 
     cerr << " AtoI conversion, character specified: " << errinfo << endl;
   return def;
}


