TXMLPlayer.cxx

Go to the documentation of this file.
00001 // @(#)root/xml:$Id: TXMLPlayer.cxx 36004 2010-10-01 12:57:36Z rdm $
00002 // Author: Sergey Linev, Rene Brun  10.05.2004
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //________________________________________________________________________
00013 //
00014 // Class for xml code generation
00015 // It should be used for generation of xml steramers, which could be used outside root
00016 // enviroment. This means, that with help of such streamers user can read and write
00017 // objects from/to xml file, which later can be accepted by ROOT.
00018 //
00019 // At the moment supported only classes, which are not inherited from TObject
00020 // and which not contains any TObject members.
00021 //
00022 // To generate xml code:
00023 //
00024 // 1. ROOT library with required classes should be created.
00025 //    In general, without such library non of user objects can be stored and
00026 //    retrived from any ROOT file
00027 //
00028 // 2. Generate xml streamers by root script like:
00029 //
00030 //    void generate() {
00031 //      gSystem->Load("libRXML.so");   // load ROOT xml library
00032 //      gSystem->Load("libuser.so");   // load user ROOT library
00033 //
00034 //      TList lst;
00035 //      lst.Add(TClass::GetClass("TUserClass1"));
00036 //      lst.Add(TClass::GetClass("TUserClass2"));
00037 //      ...
00038 //      TXMLPlayer player;
00039 //      player.ProduceCode(&lst, "streamers");    // create xml streamers
00040 //    }
00041 //
00042 //  3. Copy "streamers.h", "streamers.cxx", "TXmlFile.h", "TXmlFile.cxx" files
00043 //     to user project and compile them. TXmlFile class implementation can be taken
00044 //     from http://www-linux.gsi.de/~linev/xmlfile.tar.gz
00045 //
00046 // TXMLPlayer class generates one function per class, which called class streamer.
00047 // Name of such function for class TExample will be TExample_streamer.
00048 //
00049 // Following data members for streamed classes are supported:
00050 //  - simple data types (int, double, float)
00051 //  - array of simple types (int[5], double[5][6])
00052 //  - dynamic array of simple types (int* with comment field // [fSize])
00053 //  - const char*
00054 //  - object of any nonROOT class
00055 //  - pointer on object
00056 //  - array of objects
00057 //  - array of pointers on objects
00058 //  - stl string
00059 //  - stl vector, list, deque, set, multiset, map, multimap
00060 //  - allowed arguments for stl containers are: simple data types, string, object, pointer on object
00061 //  Any other data member can not be (yet) read from xml file and write to xml file.
00062 //
00063 // If data member of class is private or protected, it can not be accessed via
00064 // member name. Two alternative way is supported. First, if for class member fValue
00065 // exists function GetValue(), it will be used to get value from the class, and if
00066 // exists SetValue(), it will be used to set apropriate data member. Names of setter
00067 // and getter methods can be specified in comments filed like:
00068 //
00069 //     int  fValue;   // *OPTION={GetMethod="GetV";SetMethod="SetV"}
00070 //
00071 // If getter or setter methods does not available, address to data member will be
00072 // calculated as predefined offeset to object start address. In that case generated code
00073 // should be used only on the same platform (OS + compiler), where it was generated.
00074 //
00075 // Generated streamers resolve inheritance tree for given class. This allows to have
00076 // array (or vector) of object pointers on some basic class, while objects of derived
00077 // class(es) are used.
00078 //
00079 // To access data from xml files, user should use TXmlFile class, which is different from
00080 // ROOT TXMLFile, but provides very similar functionality. For example, to read
00081 // object from xml file:
00082 //
00083 //        TXmlFile file("test.xml");             // open xml file
00084 //        file.ls();                             // show list of keys in file
00085 //        TExample* ex1 = (TExample*) file.Get("ex1", TExample_streamer); // get object
00086 //        file.Close();
00087 //
00088 // To write object to file:
00089 //
00090 //        TXmlFile outfile("test2.xml", "recreate");    // create xml file
00091 //        TExample* ex1 = new TExample;
00092 //        outfile.Write(ex1, "ex1", TExample_streamer);   // write object to file
00093 //        outfile.Close();
00094 //
00095 // Complete example for generating and using of external xml streamers can be taken from
00096 // http://www-linux.gsi.de/~linev/xmlreader.tar.gz
00097 //
00098 // Any bug reports and requests for additional functionality are welcome.
00099 //
00100 // Sergey Linev, S.Linev@gsi.de
00101 //
00102 //________________________________________________________________________
00103 
00104 #include "TXMLPlayer.h"
00105 
00106 #include "Riostream.h"
00107 #include "TROOT.h"
00108 #include "TClass.h"
00109 #include "TVirtualStreamerInfo.h"
00110 #include "TStreamerElement.h"
00111 #include "TObjArray.h"
00112 #include "TObjString.h"
00113 #include "TDataMember.h"
00114 #include "TMethod.h"
00115 #include "TDataType.h"
00116 #include "TMethodCall.h"
00117 #include "TFunction.h"
00118 #include "TVirtualCollectionProxy.h"
00119 #include "TClassEdit.h"
00120 #include <string>
00121 #include <vector>
00122 
00123 const char* tab1 = "   ";
00124 const char* tab2 = "      ";
00125 const char* tab3 = "         ";
00126 const char* tab4 = "            ";
00127 
00128 const char* names_xmlfileclass = "TXmlFile";
00129 
00130 ClassImp(TXMLPlayer);
00131 
00132 //______________________________________________________________________________
00133 TXMLPlayer::TXMLPlayer() : TObject()
00134 {
00135    // default constructor
00136 }
00137 
00138 //______________________________________________________________________________
00139 TXMLPlayer::~TXMLPlayer()
00140 {
00141    // destructor of TXMLPlayer object
00142 }
00143 
00144 //______________________________________________________________________________
00145 TString TXMLPlayer::GetStreamerName(TClass* cl)
00146 {
00147    // returns streamer function name for given class
00148 
00149    if (cl==0) return "";
00150    TString res = cl->GetName();
00151    res += "_streamer";
00152    return res;
00153 }
00154 
00155 //______________________________________________________________________________
00156 Bool_t TXMLPlayer::ProduceCode(TList* cllist, const char* filename)
00157 {
00158    // Produce streamers for provide class list
00159    // TList should include list of classes, for which code should be generated.
00160    // filename specify name of file (without extension), where streamers should be
00161    // created. Function produces two files: header file and source file.
00162    // For instance, if filename is "streamers", files "streamers.h" and "streamers.cxx"
00163    // will be created.
00164 
00165    if ((cllist==0) || (filename==0)) return kFALSE;
00166 
00167    ofstream fh(TString(filename)+".h");
00168    ofstream fs(TString(filename)+".cxx");
00169 
00170    fh << "// generated header file" << endl << endl;
00171    fh << "#ifndef " << filename << "_h" << endl;
00172    fh << "#define " << filename << "_h" << endl << endl;
00173 
00174    fh << "#include \"" << names_xmlfileclass << ".h\"" << endl << endl;
00175 
00176    fs << "// generated source file" << endl << endl;
00177    fs << "#include \"" << filename << ".h\"" << endl << endl;
00178 
00179    // produce appropriate include for all classes
00180 
00181    TObjArray inclfiles;
00182    TIter iter(cllist);
00183    TClass* cl = 0;
00184    while ((cl = (TClass*) iter()) != 0) {
00185       if (inclfiles.FindObject(cl->GetDeclFileName())==0) {
00186          fs << "#include \"" << cl->GetDeclFileName() << "\"" << endl;
00187          inclfiles.Add(new TNamed(cl->GetDeclFileName(),""));
00188       }
00189    }
00190    inclfiles.Delete();
00191 
00192    fh << endl;
00193    fs << endl;
00194 
00195    // produce streamers declarations and implementations
00196 
00197    iter.Reset();
00198 
00199    while ((cl = (TClass*) iter()) != 0) {
00200 
00201       fh << "extern void* " << GetStreamerName(cl) << "("
00202          << names_xmlfileclass << " &buf, void* ptr = 0, bool checktypes = true);" << endl << endl;
00203 
00204       ProduceStreamerSource(fs, cl, cllist);
00205    }
00206 
00207    fh << "#endif" << endl << endl;
00208    fs << endl << endl;
00209 
00210    return kTRUE;
00211 }
00212 
00213 //______________________________________________________________________________
00214 TString TXMLPlayer::GetMemberTypeName(TDataMember* member)
00215 {
00216    // returns name of simple data type for given data member
00217 
00218    if (member==0) return "int";
00219 
00220    if (member->IsBasic())
00221    switch (member->GetDataType()->GetType()) {
00222       case kChar_t:     return "char";
00223       case kShort_t:    return "short";
00224       case kInt_t:      return "int";
00225       case kLong_t:     return "long";
00226       case kLong64_t:   return "long long";
00227       case kFloat16_t:
00228       case kFloat_t:    return "float";
00229       case kDouble32_t:
00230       case kDouble_t:   return "double";
00231       case kUChar_t:    {
00232          char first = member->GetDataType()->GetTypeName()[0];
00233          if ((first=='B') || (first=='b')) return "bool";
00234          return "unsigned char";
00235       }
00236       case kBool_t:     return "bool";
00237       case kUShort_t:   return "unsigned short";
00238       case kUInt_t:     return "unsigned int";
00239       case kULong_t:    return "unsigned long";
00240       case kULong64_t:  return "unsigned long long";
00241    }
00242 
00243    if (member->IsEnum()) return "int";
00244 
00245    return member->GetTypeName();
00246 }
00247 
00248 //______________________________________________________________________________
00249 TString TXMLPlayer::GetBasicTypeName(TStreamerElement* el)
00250 {
00251    // return simple data types for given TStreamerElement object
00252 
00253    if (el->GetType() == TVirtualStreamerInfo::kCounter) return "int";
00254 
00255    switch (el->GetType() % 20) {
00256       case TVirtualStreamerInfo::kChar:     return "char";
00257       case TVirtualStreamerInfo::kShort:    return "short";
00258       case TVirtualStreamerInfo::kInt:      return "int";
00259       case TVirtualStreamerInfo::kLong:     return "long";
00260       case TVirtualStreamerInfo::kLong64:   return "long long";
00261       case TVirtualStreamerInfo::kFloat16:
00262       case TVirtualStreamerInfo::kFloat:    return "float";
00263       case TVirtualStreamerInfo::kDouble32:
00264       case TVirtualStreamerInfo::kDouble:   return "double";
00265       case TVirtualStreamerInfo::kUChar: {
00266          char first = el->GetTypeNameBasic()[0];
00267          if ((first=='B') || (first=='b')) return "bool";
00268          return "unsigned char";
00269       }
00270       case TVirtualStreamerInfo::kBool:     return "bool";
00271       case TVirtualStreamerInfo::kUShort:   return "unsigned short";
00272       case TVirtualStreamerInfo::kUInt:     return "unsigned int";
00273       case TVirtualStreamerInfo::kULong:    return "unsigned long";
00274       case TVirtualStreamerInfo::kULong64:  return "unsigned long long";
00275    }
00276    return "int";
00277 }
00278 
00279 //______________________________________________________________________________
00280 TString TXMLPlayer::GetBasicTypeReaderMethodName(Int_t type, const char* realname)
00281 {
00282    // return functions name to read simple data type from xml file
00283 
00284    if (type == TVirtualStreamerInfo::kCounter) return "ReadInt";
00285 
00286    switch (type % 20) {
00287       case TVirtualStreamerInfo::kChar:     return "ReadChar";
00288       case TVirtualStreamerInfo::kShort:    return "ReadShort";
00289       case TVirtualStreamerInfo::kInt:      return "ReadInt";
00290       case TVirtualStreamerInfo::kLong:     return "ReadLong";
00291       case TVirtualStreamerInfo::kLong64:   return "ReadLong64";
00292       case TVirtualStreamerInfo::kFloat16:
00293       case TVirtualStreamerInfo::kFloat:    return "ReadFloat";
00294       case TVirtualStreamerInfo::kDouble32:
00295       case TVirtualStreamerInfo::kDouble:   return "ReadDouble";
00296       case TVirtualStreamerInfo::kUChar: {
00297          Bool_t isbool = false;
00298          if (realname!=0)
00299             isbool = (TString(realname).Index("bool",0, TString::kIgnoreCase)>=0);
00300          if (isbool) return "ReadBool";
00301          return "ReadUChar";
00302       }
00303       case TVirtualStreamerInfo::kBool:     return "ReadBool";
00304       case TVirtualStreamerInfo::kUShort:   return "ReadUShort";
00305       case TVirtualStreamerInfo::kUInt:     return "ReadUInt";
00306       case TVirtualStreamerInfo::kULong:    return "ReadULong";
00307       case TVirtualStreamerInfo::kULong64:  return "ReadULong64";
00308    }
00309    return "ReadValue";
00310 }
00311 
00312 //______________________________________________________________________________
00313 const char* TXMLPlayer::ElementGetter(TClass* cl, const char* membername, int specials)
00314 {
00315    // produce code to access member of given class.
00316    // Parameter specials has following meaning:
00317    //    0 - nothing special
00318    //    1 - cast to data type
00319    //    2 - produce pointer on given member
00320    //    3 - skip casting when produce pointer by buf.P() function
00321 
00322    TClass* membercl = cl ? cl->GetBaseDataMember(membername) : 0;
00323    TDataMember* member = membercl ? membercl->GetDataMember(membername) : 0;
00324    TMethodCall* mgetter = member ? member->GetterMethod(0) : 0;
00325 
00326    if ((mgetter!=0) && (mgetter->GetMethod()->Property() & kIsPublic)) {
00327       fGetterName = "obj->";
00328       fGetterName += mgetter->GetMethodName();
00329       fGetterName += "()";
00330    } else
00331    if ((member==0) || ((member->Property() & kIsPublic) != 0)) {
00332       fGetterName = "obj->";
00333       fGetterName += membername;
00334    } else {
00335       fGetterName = "";
00336       Bool_t deref = (member->GetArrayDim()==0) && (specials!=2);
00337       if (deref) fGetterName += "*(";
00338       if (specials!=3) {
00339          fGetterName += "(";
00340          if (member->Property() & kIsConstant) fGetterName += "const ";
00341          fGetterName += GetMemberTypeName(member);
00342          if (member->IsaPointer()) fGetterName+="*";
00343          fGetterName += "*) ";
00344       }
00345       fGetterName += "buf.P(obj,";
00346       fGetterName += member->GetOffset();
00347       fGetterName += ")";
00348       if (deref) fGetterName += ")";
00349       specials = 0;
00350    }
00351 
00352    if ((specials==1) && (member!=0)) {
00353       TString cast = "(";
00354       cast += GetMemberTypeName(member);
00355       if (member->IsaPointer() || (member->GetArrayDim()>0)) cast += "*";
00356       cast += ") ";
00357       cast += fGetterName;
00358       fGetterName = cast;
00359    }
00360 
00361    if ((specials==2) && (member!=0)) {
00362       TString buf = "&(";
00363       buf += fGetterName;
00364       buf += ")";
00365       fGetterName = buf;
00366    }
00367 
00368    return fGetterName.Data();
00369 }
00370 
00371 //______________________________________________________________________________
00372 const char* TXMLPlayer::ElementSetter(TClass* cl, const char* membername, char* endch)
00373 {
00374    // Produce code to set value to given data member.
00375    // endch should be output after value is specified.
00376 
00377    strcpy(endch,"");
00378 
00379    TClass* membercl = cl ? cl->GetBaseDataMember(membername) : 0;
00380    TDataMember* member = membercl ? membercl->GetDataMember(membername) : 0;
00381    TMethodCall* msetter = member ? member->SetterMethod(cl) : 0;
00382 
00383    if ((msetter!=0) && (msetter->GetMethod()->Property() & kIsPublic)) {
00384       fSetterName = "obj->";
00385       fSetterName += msetter->GetMethodName();
00386       fSetterName += "(";
00387       strcpy(endch,")");
00388    } else
00389    if ((member==0) || (member->Property() & kIsPublic) != 0) {
00390       fSetterName = "obj->";
00391       fSetterName += membername;
00392       fSetterName += " = ";
00393    } else {
00394       fSetterName = "";
00395       if (member->GetArrayDim()==0) fSetterName += "*";
00396       fSetterName += "((";
00397       if (member->Property() & kIsConstant) fSetterName += "const ";
00398       fSetterName += GetMemberTypeName(member);
00399       if (member->IsaPointer()) fSetterName += "*";
00400       fSetterName += "*) buf.P(obj,";
00401       fSetterName += member->GetOffset();
00402       fSetterName += ")) = ";
00403    }
00404    return fSetterName.Data();
00405 }
00406 
00407 //______________________________________________________________________________
00408 void TXMLPlayer::ProduceStreamerSource(ostream& fs, TClass* cl, TList* cllist)
00409 {
00410    // Produce source code of streamer function for specified class
00411 
00412    if (cl==0) return;
00413    TVirtualStreamerInfo* info = cl->GetStreamerInfo();
00414    TObjArray* elements = info->GetElements();
00415    if (elements==0) return;
00416 
00417    fs << "//__________________________________________________________________________" << endl;
00418    fs << "void* " << GetStreamerName(cl) << "("
00419          << names_xmlfileclass << " &buf, void* ptr, bool checktypes)" << endl;
00420    fs << "{" << endl;
00421    fs << tab1 << cl->GetName() << " *obj = (" << cl->GetName() << "*) ptr;" << endl;
00422 
00423    fs << tab1 << "if (buf.IsReading()) { " << endl;
00424 
00425    TIter iter(cllist);
00426    TClass* c1 = 0;
00427    Bool_t firstchild = true;
00428 
00429    while ((c1 = (TClass*) iter()) != 0) {
00430       if (c1==cl) continue;
00431       if (c1->GetListOfBases()->FindObject(cl->GetName())==0) continue;
00432       if (firstchild) {
00433          fs << tab2 << "if (checktypes) {" << endl;
00434          fs << tab3 << "void* ";
00435          firstchild = false;
00436       } else
00437          fs << tab3;
00438       fs << "res = " << GetStreamerName(c1)
00439          << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));" << endl;
00440       fs << tab3 << "if (res) return dynamic_cast<" << cl->GetName()
00441          << "*>(("<< c1->GetName() << " *) res);" << endl;
00442    }
00443    if (!firstchild) fs << tab2 << "}" << endl;
00444 
00445    fs << tab2 << "if (!buf.CheckClassNode(\"" << cl->GetName() << "\", "
00446               << info->GetClassVersion() << ")) return 0;" << endl;
00447 
00448    fs << tab2 << "if (obj==0) obj = new " << cl->GetName() << ";" << endl;
00449 
00450    int n;
00451    for (n=0;n<=elements->GetLast();n++) {
00452 
00453       TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n));
00454       if (el==0) continue;
00455 
00456       Int_t typ = el->GetType();
00457 
00458       switch (typ) {
00459          // basic types
00460          case TVirtualStreamerInfo::kBool:
00461          case TVirtualStreamerInfo::kChar:
00462          case TVirtualStreamerInfo::kShort:
00463          case TVirtualStreamerInfo::kInt:
00464          case TVirtualStreamerInfo::kLong:
00465          case TVirtualStreamerInfo::kLong64:
00466          case TVirtualStreamerInfo::kFloat:
00467          case TVirtualStreamerInfo::kFloat16:
00468          case TVirtualStreamerInfo::kDouble:
00469          case TVirtualStreamerInfo::kUChar:
00470          case TVirtualStreamerInfo::kUShort:
00471          case TVirtualStreamerInfo::kUInt:
00472          case TVirtualStreamerInfo::kULong:
00473          case TVirtualStreamerInfo::kULong64:
00474          case TVirtualStreamerInfo::kDouble32:
00475          case TVirtualStreamerInfo::kCounter: {
00476             char endch[5];
00477             fs << tab2 << ElementSetter(cl, el->GetName(), endch);
00478             fs << "buf." << GetBasicTypeReaderMethodName(el->GetType(), 0)
00479                << "(\"" << el->GetName() << "\")" << endch << ";" << endl;
00480             continue;
00481          }
00482 
00483          // array of basic types like bool[10]
00484          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kBool:
00485          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kChar:
00486          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kShort:
00487          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kInt:
00488          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong:
00489          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong64:
00490          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat:
00491          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat16:
00492          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble:
00493          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUChar:
00494          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUShort:
00495          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUInt:
00496          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong:
00497          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong64:
00498          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble32: {
00499             fs << tab2 << "buf.ReadArray("
00500                        << ElementGetter(cl, el->GetName(), (el->GetArrayDim()>1) ? 1 : 0);
00501             fs         << ", " << el->GetArrayLength()
00502                        << ", \"" << el->GetName() << "\");" << endl;
00503             continue;
00504          }
00505 
00506          // array of basic types like bool[n]
00507          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kBool:
00508          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kChar:
00509          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kShort:
00510          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kInt:
00511          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong:
00512          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong64:
00513          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat:
00514          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat16:
00515          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble:
00516          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUChar:
00517          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUShort:
00518          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUInt:
00519          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong:
00520          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong64:
00521          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble32: {
00522             TStreamerBasicPointer* elp = dynamic_cast<TStreamerBasicPointer*> (el);
00523             if (elp==0) {
00524                cout << "fatal error with TStreamerBasicPointer" << endl;
00525                continue;
00526             }
00527             char endch[5];
00528 
00529             fs << tab2 << ElementSetter(cl, el->GetName(), endch);
00530             fs         << "buf.ReadArray(" << ElementGetter(cl, el->GetName());
00531             fs         << ", " << ElementGetter(cl, elp->GetCountName());
00532             fs         << ", \"" << el->GetName() << "\", true)" << endch << ";" << endl;
00533             continue;
00534          }
00535 
00536          case TVirtualStreamerInfo::kCharStar: {
00537             char endch[5];
00538             fs << tab2 << ElementSetter(cl, el->GetName(), endch);
00539             fs         << "buf.ReadCharStar(" << ElementGetter(cl, el->GetName());
00540             fs         << ", \"" << el->GetName() << "\")" << endch << ";" << endl;
00541             continue;
00542          }
00543 
00544          case TVirtualStreamerInfo::kBase: {
00545             fs << tab2 << GetStreamerName(el->GetClassPointer())
00546                << "(buf, dynamic_cast<" << el->GetClassPointer()->GetName()
00547                << "*>(obj), false);" << endl;
00548             continue;
00549          }
00550 
00551          // Class*   Class not derived from TObject and with comment field //->
00552          case TVirtualStreamerInfo::kAnyp:
00553          case TVirtualStreamerInfo::kAnyp    + TVirtualStreamerInfo::kOffsetL: {
00554             if (el->GetArrayLength()>0) {
00555                fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
00556                fs         << ", " << el->GetArrayLength() << ", -1"
00557                           << ", \"" << el->GetName() << "\", "
00558                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00559             } else {
00560                fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName());
00561                fs         << ", \"" << el->GetName() << "\", "
00562                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00563             }
00564             continue;
00565          }
00566 
00567          // Class*   Class not derived from TObject and no comment
00568          case TVirtualStreamerInfo::kAnyP:
00569          case TVirtualStreamerInfo::kAnyP + TVirtualStreamerInfo::kOffsetL: {
00570             if (el->GetArrayLength()>0) {
00571                fs << tab2 << "for (int n=0;n<" << el->GetArrayLength() << ";n++) "
00572                           << "delete (" << ElementGetter(cl, el->GetName()) << ")[n];" << endl;
00573                fs << tab2 << "buf.ReadObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
00574                fs         << ", " << el->GetArrayLength()
00575                           << ", \"" << el->GetName() << "\", "
00576                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00577             } else {
00578                char endch[5];
00579 
00580                fs << tab2 << "delete " << ElementGetter(cl, el->GetName()) << ";" << endl;
00581                fs << tab2 << ElementSetter(cl, el->GetName(), endch);
00582                fs         << "(" << el->GetClassPointer()->GetName()
00583                           << "*) buf.ReadObjectPtr(\"" << el->GetName() << "\", "
00584                           << GetStreamerName(el->GetClassPointer())
00585                           << ")" <<endch << ";" << endl;
00586             }
00587             continue;
00588          }
00589 
00590          // Class  NOT derived from TObject
00591          case TVirtualStreamerInfo::kAny: {
00592             fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName(), 2);
00593             fs         << ", \"" << el->GetName() << "\", "
00594                        << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00595             continue;
00596          }
00597 
00598          // Class  NOT derived from TObject, array
00599          case TVirtualStreamerInfo::kAny + TVirtualStreamerInfo::kOffsetL: {
00600             fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
00601             fs         << ", " << el->GetArrayLength()
00602                        << ", sizeof(" << el->GetClassPointer()->GetName()
00603                        << "), \"" << el->GetName() << "\", "
00604                        << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00605             continue;
00606          }
00607 
00608          // container with no virtual table (stl) and no comment
00609          case TVirtualStreamerInfo::kSTLp:
00610          case TVirtualStreamerInfo::kSTL:
00611          case TVirtualStreamerInfo::kSTLp + TVirtualStreamerInfo::kOffsetL:
00612          case TVirtualStreamerInfo::kSTL + TVirtualStreamerInfo::kOffsetL: {
00613             TStreamerSTL* elstl = dynamic_cast<TStreamerSTL*> (el);
00614             if (elstl==0) break; // to make skip
00615 
00616             if (ProduceSTLstreamer(fs, cl, elstl, false)) continue;
00617 
00618             fs << tab2 << "// STL type = " << elstl->GetSTLtype() << endl;
00619             break;
00620          }
00621       }
00622       fs << tab2 << "buf.SkipMember(\"" << el->GetName()
00623          << "\");   // sinfo type " << el->GetType()
00624          << " of class " << el->GetClassPointer()->GetName()
00625          << " not supported" << endl;
00626    }
00627 
00628    fs << tab2 << "buf.EndClassNode();" << endl;
00629 
00630    fs << tab1 << "} else {" << endl;
00631 
00632    // generation of writing part of class streamer
00633 
00634    fs << tab2 << "if (obj==0) return 0;" << endl;
00635 
00636    firstchild = true;
00637    iter.Reset();
00638    while ((c1 = (TClass*) iter()) != 0) {
00639       if (c1==cl) continue;
00640       if (c1->GetListOfBases()->FindObject(cl->GetName())==0) continue;
00641       if (firstchild) {
00642          firstchild = false;
00643          fs << tab2 << "if (checktypes) {" << endl;
00644       }
00645       fs << tab3 << "if (dynamic_cast<" << c1->GetName() << "*>(obj))" << endl;
00646       fs << tab4 << "return " << GetStreamerName(c1) << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));" << endl;
00647    }
00648    if (!firstchild) fs << tab2 << "}" << endl;
00649 
00650    fs << tab2 << "buf.StartClassNode(\"" << cl->GetName() << "\", "
00651               << info->GetClassVersion() << ");" << endl;
00652 
00653    for (n=0;n<=elements->GetLast();n++) {
00654 
00655       TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n));
00656       if (el==0) continue;
00657 
00658       Int_t typ = el->GetType();
00659 
00660       switch (typ) {
00661          // write basic types
00662          case TVirtualStreamerInfo::kBool:
00663          case TVirtualStreamerInfo::kChar:
00664          case TVirtualStreamerInfo::kShort:
00665          case TVirtualStreamerInfo::kInt:
00666          case TVirtualStreamerInfo::kLong:
00667          case TVirtualStreamerInfo::kLong64:
00668          case TVirtualStreamerInfo::kFloat:
00669          case TVirtualStreamerInfo::kFloat16:
00670          case TVirtualStreamerInfo::kDouble:
00671          case TVirtualStreamerInfo::kUChar:
00672          case TVirtualStreamerInfo::kUShort:
00673          case TVirtualStreamerInfo::kUInt:
00674          case TVirtualStreamerInfo::kULong:
00675          case TVirtualStreamerInfo::kULong64:
00676          case TVirtualStreamerInfo::kDouble32:
00677          case TVirtualStreamerInfo::kCounter: {
00678             fs << tab2 << "buf.WriteValue(";
00679             if (typ==TVirtualStreamerInfo::kUChar)
00680                fs <<"(unsigned char) " << ElementGetter(cl, el->GetName());
00681             else
00682                fs << ElementGetter(cl, el->GetName());
00683             fs << ", \"" << el->GetName() << "\");" << endl;
00684             continue;
00685          }
00686 
00687          // array of basic types
00688          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kBool:
00689          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kChar:
00690          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kShort:
00691          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kInt:
00692          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong:
00693          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kLong64:
00694          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat:
00695          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kFloat16:
00696          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble:
00697          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUChar:
00698          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUShort:
00699          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUInt:
00700          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong:
00701          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kULong64:
00702          case TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kDouble32: {
00703             fs << tab2 << "buf.WriteArray("
00704                        << ElementGetter(cl, el->GetName(), (el->GetArrayDim()>1) ? 1 : 0);
00705             fs         << ", " << el->GetArrayLength()
00706                        << ", \"" << el->GetName() << "\");" << endl;
00707             continue;
00708          }
00709 
00710          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kBool:
00711          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kChar:
00712          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kShort:
00713          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kInt:
00714          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong:
00715          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kLong64:
00716          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat:
00717          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kFloat16:
00718          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble:
00719          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUChar:
00720          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUShort:
00721          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kUInt:
00722          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong:
00723          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kULong64:
00724          case TVirtualStreamerInfo::kOffsetP + TVirtualStreamerInfo::kDouble32: {
00725             TStreamerBasicPointer* elp = dynamic_cast<TStreamerBasicPointer*> (el);
00726             if (elp==0) {
00727                cout << "fatal error with TStreamerBasicPointer" << endl;
00728                continue;
00729             }
00730             fs << tab2 << "buf.WriteArray(" << ElementGetter(cl, el->GetName());
00731             fs         << ", " << ElementGetter(cl, elp->GetCountName())
00732                        << ", \"" << el->GetName() << "\", true);" << endl;
00733             continue;
00734          }
00735 
00736          case TVirtualStreamerInfo::kCharStar: {
00737             fs << tab2 << "buf.WriteCharStar(" << ElementGetter(cl, el->GetName())
00738                        << ", \"" << el->GetName() << "\");" << endl;
00739             continue;
00740          }
00741 
00742          case TVirtualStreamerInfo::kBase: {
00743             fs << tab2 << GetStreamerName(el->GetClassPointer())
00744                << "(buf, dynamic_cast<" << el->GetClassPointer()->GetName()
00745                << "*>(obj), false);" << endl;
00746             continue;
00747          }
00748 
00749          // Class*   Class not derived from TObject and with comment field //->
00750          case TVirtualStreamerInfo::kAnyp:
00751          case TVirtualStreamerInfo::kAnyp    + TVirtualStreamerInfo::kOffsetL: {
00752             if (el->GetArrayLength()>0) {
00753                fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
00754                fs         << ", " << el->GetArrayLength() << ", -1"
00755                           << ", \"" << el->GetName() << "\", "
00756                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00757             } else {
00758                fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName());
00759                fs         << ", \"" << el->GetName() << "\", "
00760                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00761             }
00762             continue;
00763          }
00764 
00765          // Class*   Class not derived from TObject and no comment
00766          case TVirtualStreamerInfo::kAnyP:
00767          case TVirtualStreamerInfo::kAnyP + TVirtualStreamerInfo::kOffsetL: {
00768             if (el->GetArrayLength()>0) {
00769                fs << tab2 << "buf.WriteObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
00770                fs         << ", " << el->GetArrayLength()
00771                           << ", \"" << el->GetName() << "\", "
00772                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00773             } else {
00774                fs << tab2 << "buf.WriteObjectPtr(" << ElementGetter(cl, el->GetName());
00775                fs         << ", \"" << el->GetName() << "\", "
00776                           << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00777             }
00778             continue;
00779          }
00780 
00781          case TVirtualStreamerInfo::kAny: {    // Class  NOT derived from TObject
00782             fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName(), 2);
00783             fs         << ", \"" << el->GetName() << "\", "
00784                        << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00785             continue;
00786          }
00787 
00788          case TVirtualStreamerInfo::kAny    + TVirtualStreamerInfo::kOffsetL: {
00789             fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
00790             fs         << ", " << el->GetArrayLength()
00791                        << ", sizeof(" << el->GetClassPointer()->GetName()
00792                        << "), \"" << el->GetName() << "\", "
00793                        << GetStreamerName(el->GetClassPointer()) << ");" << endl;
00794             continue;
00795          }
00796 
00797          // container with no virtual table (stl) and no comment
00798          case TVirtualStreamerInfo::kSTLp + TVirtualStreamerInfo::kOffsetL:
00799          case TVirtualStreamerInfo::kSTL + TVirtualStreamerInfo::kOffsetL:
00800          case TVirtualStreamerInfo::kSTLp:
00801          case TVirtualStreamerInfo::kSTL: {
00802             TStreamerSTL* elstl = dynamic_cast<TStreamerSTL*> (el);
00803             if (elstl==0) break; // to make skip
00804 
00805             if (ProduceSTLstreamer(fs, cl, elstl, true)) continue;
00806             fs << tab2 << "// STL type = " << elstl->GetSTLtype() << endl;
00807             break;
00808          }
00809 
00810       }
00811       fs << tab2 << "buf.MakeEmptyMember(\"" << el->GetName()
00812                  << "\");   // sinfo type " << el->GetType()
00813                  << " of class " << el->GetClassPointer()->GetName()
00814                  << " not supported" << endl;
00815    }
00816 
00817    fs << tab2 << "buf.EndClassNode();" << endl;
00818 
00819    fs << tab1 << "}" << endl;
00820    fs << tab1 << "return obj;" << endl;
00821    fs << "}" << endl << endl;
00822 }
00823 
00824 //______________________________________________________________________________
00825 void TXMLPlayer::ReadSTLarg(ostream& fs,
00826                             TString& argname,
00827                             int argtyp,
00828                             Bool_t isargptr,
00829                             TClass* argcl,
00830                             TString& tname,
00831                             TString& ifcond)
00832 {
00833    // Produce code to read argument of stl container from xml file
00834 
00835    switch(argtyp) {
00836       case TVirtualStreamerInfo::kBool:
00837       case TVirtualStreamerInfo::kChar:
00838       case TVirtualStreamerInfo::kShort:
00839       case TVirtualStreamerInfo::kInt:
00840       case TVirtualStreamerInfo::kLong:
00841       case TVirtualStreamerInfo::kLong64:
00842       case TVirtualStreamerInfo::kFloat:
00843       case TVirtualStreamerInfo::kFloat16:
00844       case TVirtualStreamerInfo::kDouble:
00845       case TVirtualStreamerInfo::kUChar:
00846       case TVirtualStreamerInfo::kUShort:
00847       case TVirtualStreamerInfo::kUInt:
00848       case TVirtualStreamerInfo::kULong:
00849       case TVirtualStreamerInfo::kULong64:
00850       case TVirtualStreamerInfo::kDouble32:
00851       case TVirtualStreamerInfo::kCounter: {
00852          fs << tname << " " << argname << " = buf."
00853             << GetBasicTypeReaderMethodName(argtyp, tname.Data()) << "(0);" << endl;
00854          break;
00855       }
00856 
00857       case TVirtualStreamerInfo::kObject: {
00858          fs << tname << (isargptr ? " ": " *") << argname << " = "
00859             << "(" << argcl->GetName() << "*)"
00860             << "buf.ReadObjectPtr(0, "
00861             << GetStreamerName(argcl) << ");" << endl;
00862          if (!isargptr) {
00863             if (ifcond.Length()>0) ifcond+=" && ";
00864             ifcond += argname;
00865             TString buf = "*";
00866             buf += argname;
00867             argname = buf;
00868          }
00869          break;
00870       }
00871 
00872       case TVirtualStreamerInfo::kSTLstring: {
00873          fs << "string *" << argname << " = "
00874             << "buf.ReadSTLstring();" << endl;
00875          if (!isargptr) {
00876             if (ifcond.Length()>0) ifcond+=" && ";
00877             ifcond += argname;
00878             TString buf = "*";
00879             buf += argname;
00880             argname = buf;
00881          }
00882          break;
00883       }
00884 
00885       default:
00886          fs << "/* argument " << argname << " not supported */";
00887    }
00888 }
00889 
00890 //______________________________________________________________________________
00891 void TXMLPlayer::WriteSTLarg(ostream& fs, const char* accname, int argtyp, Bool_t isargptr, TClass* argcl)
00892 {
00893    // Produce code to write argument of stl container to xml file
00894 
00895    switch(argtyp) {
00896       case TVirtualStreamerInfo::kBool:
00897       case TVirtualStreamerInfo::kChar:
00898       case TVirtualStreamerInfo::kShort:
00899       case TVirtualStreamerInfo::kInt:
00900       case TVirtualStreamerInfo::kLong:
00901       case TVirtualStreamerInfo::kLong64:
00902       case TVirtualStreamerInfo::kFloat:
00903       case TVirtualStreamerInfo::kFloat16:
00904       case TVirtualStreamerInfo::kDouble:
00905       case TVirtualStreamerInfo::kUChar:
00906       case TVirtualStreamerInfo::kUShort:
00907       case TVirtualStreamerInfo::kUInt:
00908       case TVirtualStreamerInfo::kULong:
00909       case TVirtualStreamerInfo::kULong64:
00910       case TVirtualStreamerInfo::kDouble32:
00911       case TVirtualStreamerInfo::kCounter: {
00912          fs << "buf.WriteValue(" << accname << ", 0);" << endl;
00913          break;
00914       }
00915 
00916       case TVirtualStreamerInfo::kObject: {
00917          fs << "buf.WriteObjectPtr(";
00918          if (isargptr)
00919             fs << accname;
00920          else
00921             fs << "&(" << accname << ")";
00922          fs << ", 0, " <<  GetStreamerName(argcl) << ");" << endl;
00923          break;
00924       }
00925 
00926       case TVirtualStreamerInfo::kSTLstring: {
00927          fs << "buf.WriteSTLstring(";
00928          if (isargptr)
00929             fs << accname;
00930          else
00931             fs << "&(" << accname << ")";
00932          fs << ");" << endl;
00933          break;
00934       }
00935 
00936       default:
00937          fs << "/* argument not supported */" << endl;
00938    }
00939 }
00940 
00941 //______________________________________________________________________________
00942 Bool_t TXMLPlayer::ProduceSTLstreamer(ostream& fs, TClass* cl, TStreamerSTL* el, Bool_t isWriting)
00943 {
00944    // Produce code of xml streamer for data member of stl type
00945 
00946    if ((cl==0) || (el==0)) return false;
00947 
00948    TClass* contcl = el->GetClassPointer();
00949 
00950    Bool_t isstr = (el->GetSTLtype() == TStreamerElement::kSTLstring);
00951    Bool_t isptr = el->IsaPointer();
00952    Bool_t isarr = (el->GetArrayLength()>0);
00953    Bool_t isparent = (strcmp(el->GetName(), contcl->GetName())==0);
00954 
00955    int stltyp = -1;
00956    int narg = 0;
00957    int argtype[2];
00958    Bool_t isargptr[2];
00959    TClass* argcl[2];
00960    TString argtname[2];
00961 
00962    if (isstr)
00963       stltyp = TStreamerElement::kSTLstring;
00964    else
00965       if (TClassEdit::IsSTLCont(contcl->GetName())) {
00966          string shortTypeName =
00967             TClassEdit::ShortType(contcl->GetName(), TClassEdit::kDropStlDefault);
00968          int nestedLoc = 0;
00969          vector<string> splitName;
00970          TClassEdit::GetSplit(shortTypeName.c_str(), splitName, nestedLoc);
00971 
00972          stltyp = TClassEdit::STLKind(splitName[0].c_str());
00973          switch (stltyp) {
00974             case TClassEdit::kVector   : narg = 1; break;
00975             case TClassEdit::kList     : narg = 1; break;
00976             case TClassEdit::kDeque    : narg = 1; break;
00977             case TClassEdit::kMap      : narg = 2; break;
00978             case TClassEdit::kMultiMap : narg = 2; break;
00979             case TClassEdit::kSet      : narg = 1; break;
00980             case TClassEdit::kMultiSet : narg = 1; break;
00981             default: return false;
00982          }
00983 
00984          for(int n=0;n<narg;n++) {
00985             argtype[n] = -1;
00986             isargptr[n] = false;
00987             argcl[n] = 0;
00988             argtname[n] = "";
00989 
00990             TString buf = splitName[n+1];
00991 
00992             argtname[n] = buf;
00993 
00994             // nested STL containers not yet supported
00995             if (TClassEdit::IsSTLCont(buf.Data())) return false;
00996 
00997             int pstar = buf.Index("*");
00998 
00999             if (pstar>0) {
01000                isargptr[n] = true;
01001                pstar--;
01002                while ((pstar>0) && (buf[pstar]==' ')) pstar--;
01003                buf.Remove(pstar+1);
01004             } else
01005                isargptr[n] = false;
01006 
01007             if (buf.Index("const ")==0) {
01008                buf.Remove(0,6);
01009                while ((buf.Length()>0) && (buf[0]==' ')) buf.Remove(0,1);
01010             }
01011 
01012             TDataType *dt = (TDataType*)gROOT->GetListOfTypes()->FindObject(buf);
01013             if (dt) argtype[n] = dt->GetType(); else
01014             if (buf=="string")
01015                argtype[n] = TVirtualStreamerInfo::kSTLstring;
01016             else {
01017                argcl[n] = TClass::GetClass(buf);
01018                if (argcl[n]!=0) argtype[n]=TVirtualStreamerInfo::kObject;
01019             }
01020             if (argtype[n]<0) stltyp = -1;
01021          } // for narg
01022 
01023       if (stltyp<0) return false;
01024    }
01025 
01026    Bool_t akaarrayaccess = (narg==1) && (argtype[0]<20);
01027 
01028    char tabs[30], tabs2[30];
01029 
01030    if (isWriting) {
01031 
01032       fs << tab2 << "if (buf.StartSTLnode(\""
01033                  << fXmlSetup.XmlGetElementName(el) << "\")) {" << endl;
01034 
01035       fs << tab3 << contcl->GetName() << " ";
01036 
01037       TString accname;
01038       if (isptr) {
01039          if (isarr) { fs << "**cont"; accname = "(*cont)->"; }
01040             else { fs << "*cont"; accname = "cont->"; }
01041       } else
01042       if (isarr) { fs << "*cont"; accname = "cont->"; }
01043          else { fs << "&cont"; accname = "cont."; }
01044 
01045       fs << " = ";
01046 
01047       if (isparent)
01048          fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << endl;
01049       else
01050          fs << ElementGetter(cl, el->GetName()) << ";" << endl;
01051 
01052       if (isarr && el->GetArrayLength()) {
01053          strlcpy(tabs, tab4, sizeof(tabs));
01054          fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << endl;
01055       } else
01056          strlcpy(tabs, tab3, sizeof(tabs));
01057 
01058       strlcpy(tabs2, tabs, sizeof(tabs2));
01059 
01060       if (isptr) {
01061          strlcat(tabs2, tab1, sizeof(tabs2));
01062          fs << tabs << "if (" << (isarr ? "*cont" : "cont") << "==0) {" << endl;
01063          fs << tabs2 << "buf.WriteSTLsize(0" << (isstr ? ",true);" : ");") << endl;
01064          fs << tabs << "} else {" << endl;
01065       }
01066 
01067       fs << tabs2 << "buf.WriteSTLsize(" << accname
01068                   << (isstr ? "length(), true);" : "size());") << endl;
01069 
01070       if (isstr) {
01071          fs << tabs2 << "buf.WriteSTLstringData(" << accname << "c_str());" << endl;
01072       } else {
01073          if (akaarrayaccess) {
01074             fs << tabs2 << argtname[0] << "* arr = new " << argtname[0]
01075                                        << "[" << accname << "size()];" << endl;
01076             fs << tabs2 << "int k = 0;" << endl;
01077          }
01078 
01079          fs << tabs2 << contcl->GetName() << "::const_iterator iter;" << endl;
01080          fs << tabs2 << "for (iter = " << accname << "begin(); iter != "
01081                     << accname << "end(); iter++)";
01082          if (akaarrayaccess) {
01083             fs << endl << tabs2 << tab1 << "arr[k++] = *iter;" << endl;
01084             fs << tabs2 << "buf.WriteArray(arr, " << accname << "size(), 0, false);" << endl;
01085             fs << tabs2 << "delete[] arr;" << endl;
01086          } else
01087          if (narg==1) {
01088             fs << endl << tabs2 << tab1;
01089             WriteSTLarg(fs, "*iter", argtype[0], isargptr[0], argcl[0]);
01090          } else
01091          if (narg==2) {
01092             fs << " {" << endl;
01093             fs << tabs2 << tab1;
01094             WriteSTLarg(fs, "iter->first", argtype[0], isargptr[0], argcl[0]);
01095             fs << tabs2 << tab1;
01096             WriteSTLarg(fs, "iter->second", argtype[1], isargptr[1], argcl[1]);
01097             fs << tabs2 << "}" << endl;
01098          }
01099       } // if (isstr)
01100 
01101       if (isptr) fs << tabs << "}" << endl;
01102 
01103       if (isarr && el->GetArrayLength()) {
01104          if (isptr)
01105             fs << tabs << "cont++;" << endl;
01106          else
01107             fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << endl;
01108          fs << tab3 << "}" << endl;
01109       }
01110 
01111       fs << tab3 << "buf.EndSTLnode();" << endl;
01112       fs << tab2 << "}" << endl;
01113 
01114    } else {
01115 
01116 
01117       fs << tab2 << "if (buf.VerifySTLnode(\""
01118                  << fXmlSetup.XmlGetElementName(el) << "\")) {" << endl;
01119 
01120       fs << tab3 << contcl->GetName() << " ";
01121       TString accname, accptr;
01122       if (isptr) {
01123          if (isarr) { fs << "**cont"; accname = "(*cont)->"; accptr = "*cont"; }
01124             else { fs << "*cont"; accname = "cont->"; accptr = "cont"; }
01125       } else
01126       if (isarr) { fs << "*cont"; accname = "cont->"; }
01127          else { fs << "&cont"; accname = "cont."; }
01128 
01129       fs << " = ";
01130 
01131       if (isparent)
01132          fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << endl;
01133       else
01134          fs << ElementGetter(cl, el->GetName()) << ";" << endl;
01135 
01136       if (isarr && el->GetArrayLength()) {
01137          strlcpy(tabs, tab4, sizeof(tabs));
01138          fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << endl;
01139       } else
01140          strlcpy(tabs, tab3, sizeof(tabs));
01141 
01142       fs << tabs << "int size = buf.ReadSTLsize(" << (isstr ? "true);" : ");") << endl;
01143 
01144       if (isptr) {
01145          fs << tabs << "delete " << accptr << ";" << endl;
01146          fs << tabs << "if (size==0) " << accptr << " = 0;" << endl;
01147          fs << tabs << "        else " << accptr << " = new " << contcl->GetName() << ";" << endl;
01148          if (!isarr) {
01149             char endch[5];
01150             fs << tabs << ElementSetter(cl, el->GetName(), endch);
01151             fs         << "cont" << endch << ";" << endl;
01152          }
01153       } else {
01154          fs << tabs << accname << (isstr ? "erase();" : "clear();") << endl;
01155       }
01156 
01157       if (isstr) {
01158          fs << tabs << "if (size>0) " << accname << "assign(buf.ReadSTLstringData(size));" << endl;
01159       } else {
01160          if (akaarrayaccess) {
01161             fs << tabs << argtname[0] << "* arr = new " << argtname[0] << "[size];" << endl;
01162             fs << tabs << "buf.ReadArray(arr, size, 0, false);" << endl;
01163          }
01164 
01165          fs << tabs << "for(int k=0;k<size;k++)";
01166 
01167          if (akaarrayaccess) {
01168             fs << endl << tabs << tab1 << accname;
01169             if ((stltyp==TClassEdit::kSet) || (stltyp==TClassEdit::kMultiSet))
01170                fs << "insert"; else fs << "push_back";
01171             fs << "(arr[k]);" << endl;
01172             fs << tabs << "delete[] arr;" << endl;
01173          } else
01174          if (narg==1) {
01175             TString arg1("arg"), ifcond;
01176             fs << " {" << endl << tabs << tab1;
01177             ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
01178             fs << tabs << tab1;
01179             if (ifcond.Length()>0) fs << "if (" << ifcond << ") ";
01180             fs << accname;
01181             if ((stltyp==TClassEdit::kSet) || (stltyp==TClassEdit::kMultiSet))
01182                fs << "insert";
01183             else
01184                fs << "push_back";
01185             fs << "(" << arg1 << ");" << endl;
01186             fs << tabs << "}" << endl;
01187          } else
01188          if (narg==2) {
01189             TString arg1("arg1"), arg2("arg2"), ifcond;
01190             fs << " {" << endl << tabs << tab1;
01191             ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
01192             fs << tabs << tab1;
01193             ReadSTLarg(fs, arg2, argtype[1], isargptr[1], argcl[1], argtname[1], ifcond);
01194             fs << tabs << tab1;
01195             if (ifcond.Length()>0) fs << "if (" << ifcond << ") ";
01196             fs << accname << "insert(make_pair("
01197                << arg1 << ", " << arg2 << "));" << endl;
01198             fs << tabs << "}" << endl;
01199          }
01200       }
01201 
01202       if (isarr && el->GetArrayLength()) {
01203          if (isptr) fs << tabs << "cont++;" << endl;
01204          else fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << endl;
01205          fs << tab3 << "}" << endl;
01206       }
01207 
01208       fs << tab3 << "buf.EndSTLnode();" << endl;
01209       fs << tab2 << "}" << endl;
01210    }
01211    return true;
01212 }

Generated on Tue Jul 5 14:30:39 2011 for ROOT_528-00b_version by  doxygen 1.5.1