TBufferXML.cxx

Go to the documentation of this file.
00001 // @(#)root/:$Id: TBufferXML.cxx 36080 2010-10-05 10:44:49Z 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 serializing/deserializing object to/from xml.
00015 // It redefines most of TBuffer class function to convert simple types,
00016 // array of simple types and objects to/from xml.
00017 // Instead of writing a binary data it creates a set of xml structures as
00018 // nodes and attributes
00019 // TBufferXML class uses streaming mechanism, provided by ROOT system,
00020 // therefore most of ROOT and user classes can be stored to xml. There are
00021 // limitations for complex objects like TTree, which can not be yet converted to xml.
00022 //________________________________________________________________________
00023 
00024 
00025 #include "TBufferXML.h"
00026 #include "TXMLFile.h"
00027 
00028 #include "TObjArray.h"
00029 #include "TROOT.h"
00030 #include "TClass.h"
00031 #include "TClassTable.h"
00032 #include "TDataType.h"
00033 #include "TExMap.h"
00034 #include "TMethodCall.h"
00035 #include "TStreamerInfo.h"
00036 #include "TStreamerElement.h"
00037 #include "TProcessID.h"
00038 #include "TFile.h"
00039 #include "TMemberStreamer.h"
00040 #include "TStreamer.h"
00041 #include "TStreamerInfoActions.h"
00042 
00043 extern "C" void R__zip(int cxlevel, int *srcsize, char *src, int *tgtsize, char *tgt, int *irep);
00044 
00045 extern "C" void R__unzip(int *srcsize, unsigned char *src, int *tgtsize, unsigned char *tgt, int *irep);
00046 
00047 #ifdef R__VISUAL_CPLUSPLUS
00048 #define FLong64    "%I64d"
00049 #define FULong64   "%I64u"
00050 #else
00051 #define FLong64    "%lld"
00052 #define FULong64   "%llu"
00053 #endif
00054 
00055 ClassImp(TBufferXML);
00056 
00057 
00058 const char* TBufferXML::fgFloatFmt = "%e";
00059 
00060 //______________________________________________________________________________
00061 TBufferXML::TBufferXML() :
00062    TBufferFile(),
00063    TXMLSetup(),
00064    fXML(0),
00065    fStack(),
00066    fVersionBuf(-111),
00067    fObjMap(0),
00068    fIdArray(0),
00069    fErrorFlag(0),
00070    fCanUseCompact(kFALSE),
00071    fExpectedChain(kFALSE),
00072    fExpectedBaseClass(0),
00073    fCompressLevel(0)
00074 
00075 {
00076    // Default constructor
00077 }
00078 
00079 //______________________________________________________________________________
00080 TBufferXML::TBufferXML(TBuffer::EMode mode) :
00081    TBufferFile(mode),
00082    TXMLSetup(),
00083    fXML(0),
00084    fStack(),
00085    fVersionBuf(-111),
00086    fObjMap(0),
00087    fIdArray(0),
00088    fErrorFlag(0),
00089    fCanUseCompact(kFALSE),
00090    fExpectedChain(kFALSE),
00091    fExpectedBaseClass(0),
00092    fCompressLevel(0)
00093 {
00094    // Creates buffer object to serailize/deserialize data to/from xml.
00095    // Mode should be either TBuffer::kRead or TBuffer::kWrite.
00096 
00097    fBufSize = 1000000000;
00098 
00099    SetParent(0);
00100    SetBit(kCannotHandleMemberWiseStreaming);
00101    SetBit(kTextBasedStreaming);
00102 }
00103 
00104 //______________________________________________________________________________
00105 TBufferXML::TBufferXML(TBuffer::EMode mode, TXMLFile* file) :
00106    TBufferFile(mode),
00107    TXMLSetup(*file),
00108    fStack(),
00109    fVersionBuf(-111),
00110    fObjMap(0),
00111    fIdArray(0),
00112    fErrorFlag(0),
00113    fCanUseCompact(kFALSE),
00114    fExpectedChain(kFALSE),
00115    fExpectedBaseClass(0),
00116    fCompressLevel(0)
00117 {
00118    // Creates buffer object to serailize/deserialize data to/from xml.
00119    // This constructor should be used, if data from buffer supposed to be stored in file.
00120    // Mode should be either TBuffer::kRead or TBuffer::kWrite.
00121 
00122    // this is for the case when StreamerInfo reads elements from
00123    // buffer as ReadFastArray. When it checks if size of buffer is
00124    // too small and skip reading. Actually, more improved method should
00125    // be used here.
00126    fBufSize = 1000000000;
00127 
00128    SetParent(file);
00129    SetBit(kCannotHandleMemberWiseStreaming);
00130    SetBit(kTextBasedStreaming);
00131    if (XmlFile()) {
00132       SetXML(XmlFile()->XML());
00133       SetCompressionLevel(XmlFile()->GetCompressionLevel());
00134    }
00135 }
00136 
00137 //______________________________________________________________________________
00138 TBufferXML::~TBufferXML()
00139 {
00140    // destroy xml buffer
00141 
00142    if (fObjMap) delete fObjMap;
00143    if (fIdArray) delete fIdArray;
00144    fStack.Delete();
00145 }
00146 
00147 //______________________________________________________________________________
00148 TXMLFile* TBufferXML::XmlFile()
00149 {
00150    // returns pointer to TXMLFile object
00151    // access to file is necessary to produce unique identifier for object references
00152 
00153    return dynamic_cast<TXMLFile*>(GetParent());
00154 }
00155 
00156 //______________________________________________________________________________
00157 TString TBufferXML::ConvertToXML(TObject* obj, Bool_t GenericLayout, Bool_t UseNamespaces)
00158 {
00159    // converts object, inherited from TObject class, to XML string
00160    // fmt contains configuration of XML layout. See TXMLSetup class for detatils
00161 
00162    return ConvertToXML(obj, obj ? obj->IsA() : 0, GenericLayout, UseNamespaces);
00163 }
00164 
00165 //______________________________________________________________________________
00166 TString TBufferXML::ConvertToXML(void* obj, TClass* cl, Bool_t GenericLayout, Bool_t UseNamespaces)
00167 {
00168    // converts any type of object to XML string
00169    // fmt contains configuration of XML layout. See TXMLSetup class for detatils
00170 
00171    TXMLEngine xml;
00172 
00173    TBufferXML buf(TBuffer::kWrite);
00174    buf.SetXML(&xml);
00175 
00176    buf.SetXmlLayout(GenericLayout ? TXMLSetup::kGeneralized : TXMLSetup::kSpecialized);
00177    buf.SetUseNamespaces(UseNamespaces);
00178 
00179    XMLNodePointer_t xmlnode = buf.XmlWriteAny(obj, cl);
00180 
00181    TString res;
00182 
00183    xml.SaveSingleNode(xmlnode, &res);
00184 
00185    xml.FreeNode(xmlnode);
00186 
00187    return res;
00188 }
00189 
00190 //______________________________________________________________________________
00191 TObject* TBufferXML::ConvertFromXML(const char* str, Bool_t GenericLayout, Bool_t UseNamespaces)
00192 {
00193    // Read object from XML, produced by ConvertToXML() method.
00194    // If object does not inherit from TObject class, return 0.
00195    // GenericLayout and UseNamespaces should be the same as in ConvertToXML()
00196 
00197    TClass* cl = 0;
00198    void* obj = ConvertFromXMLAny(str, &cl, GenericLayout, UseNamespaces);
00199 
00200    if ((cl==0) || (obj==0)) return 0;
00201 
00202    Int_t delta = cl->GetBaseClassOffset(TObject::Class());
00203 
00204    if (delta<0) {
00205       cl->Destructor(obj);
00206       return 0;
00207    }
00208 
00209    return (TObject*) ( ( (char*)obj ) + delta );
00210 }
00211 
00212 //______________________________________________________________________________
00213 void* TBufferXML::ConvertFromXMLAny(const char* str, TClass** cl, Bool_t GenericLayout, Bool_t UseNamespaces)
00214 {
00215    // Read object of any class from XML, produced by ConvertToXML() method.
00216    // If cl!=0, return actual class of object.
00217    // GenericLayout and UseNamespaces should be the same as in ConvertToXML()
00218 
00219    TXMLEngine xml;
00220    TBufferXML buf(TBuffer::kRead);
00221 
00222    buf.SetXML(&xml);
00223 
00224    buf.SetXmlLayout(GenericLayout ? TXMLSetup::kGeneralized : TXMLSetup::kSpecialized);
00225    buf.SetUseNamespaces(UseNamespaces);
00226 
00227    XMLNodePointer_t xmlnode = xml.ReadSingleNode(str);
00228 
00229    void* obj = buf.XmlReadAny(xmlnode, 0, cl);
00230 
00231    xml.FreeNode(xmlnode);
00232 
00233    return obj;
00234 }
00235 
00236 //______________________________________________________________________________
00237 XMLNodePointer_t TBufferXML::XmlWriteAny(const void* obj, const TClass* cl)
00238 {
00239    // Convert object of any class to xml structures
00240    // Return pointer on top xml element
00241 
00242    fErrorFlag = 0;
00243 
00244    if (fXML==0) return 0;
00245 
00246    XMLNodePointer_t res = XmlWriteObject(obj, cl);
00247 
00248    return res;
00249 }
00250 
00251 //______________________________________________________________________________
00252 void* TBufferXML::XmlReadAny(XMLNodePointer_t node, void* obj, TClass** cl)
00253 {
00254    // Recreate object from xml structure.
00255    // Return pointer to read object.
00256    // if (cl!=0) returns pointer to class of object
00257 
00258    if (node==0) return 0;
00259    if (cl) *cl = 0;
00260 
00261    fErrorFlag = 0;
00262 
00263    if (fXML==0) return 0;
00264 
00265    PushStack(node, kTRUE);
00266 
00267    void* res = XmlReadObject(obj, cl);
00268 
00269    PopStack();
00270 
00271    return res;
00272 }
00273 
00274 //______________________________________________________________________________
00275 void TBufferXML::WriteObject(const TObject *obj)
00276 {
00277    // Convert object into xml structures.
00278    // !!! Should be used only by TBufferXML itself.
00279    // Use ConvertToXML() methods to convert your object to xml
00280    // Redefined here to avoid gcc 3.x warning
00281 
00282    TBufferFile::WriteObject(obj);
00283 }
00284 
00285 // TXMLStackObj is used to keep stack of object hierarchy,
00286 // stored in TBuffer. For instnace, data for parent class(es)
00287 // stored in subnodes, but initial object node will be kept.
00288 
00289 class TXMLStackObj : public TObject {
00290    public:
00291       TXMLStackObj(XMLNodePointer_t node) :
00292          TObject(),
00293          fNode(node),
00294          fInfo(0),
00295          fElem(0),
00296          fElemNumber(0),
00297          fCompressedClassNode(kFALSE),
00298          fClassNs(0),
00299          fIsStreamerInfo(kFALSE),
00300          fIsElemOwner(kFALSE)
00301           {}
00302 
00303       virtual ~TXMLStackObj()
00304       {
00305          if (fIsElemOwner) delete fElem;
00306       }
00307 
00308       Bool_t IsStreamerInfo() const { return fIsStreamerInfo; }
00309 
00310       XMLNodePointer_t  fNode;
00311       TStreamerInfo*    fInfo;
00312       TStreamerElement* fElem;
00313       Int_t             fElemNumber;
00314       Bool_t            fCompressedClassNode;
00315       XMLNsPointer_t    fClassNs;
00316       Bool_t            fIsStreamerInfo;
00317       Bool_t            fIsElemOwner;
00318 };
00319 
00320 //______________________________________________________________________________
00321 TXMLStackObj* TBufferXML::PushStack(XMLNodePointer_t current, Bool_t simple)
00322 {
00323    // add new level to xml stack
00324 
00325    if (IsReading() && !simple) {
00326       current = fXML->GetChild(current);
00327       fXML->SkipEmpty(current);
00328    }
00329 
00330    TXMLStackObj* stack = new TXMLStackObj(current);
00331    fStack.Add(stack);
00332    return stack;
00333 }
00334 
00335 //______________________________________________________________________________
00336 TXMLStackObj* TBufferXML::PopStack()
00337 {
00338    // remove one level from xml stack
00339 
00340    TObject* last = fStack.Last();
00341    if (last!=0) {
00342       fStack.Remove(last);
00343       delete last;
00344       fStack.Compress();
00345    }
00346    return dynamic_cast<TXMLStackObj*> (fStack.Last());
00347 }
00348 
00349 //______________________________________________________________________________
00350 TXMLStackObj* TBufferXML::Stack(Int_t depth)
00351 {
00352    // return xml stack object of specified depth
00353 
00354    TXMLStackObj* stack = 0;
00355    if (depth<=fStack.GetLast())
00356       stack = dynamic_cast<TXMLStackObj*> (fStack.At(fStack.GetLast()-depth));
00357    return stack;
00358 }
00359 
00360 //______________________________________________________________________________
00361 XMLNodePointer_t TBufferXML::StackNode()
00362 {
00363    // return pointer on current xml node
00364 
00365    TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last());
00366    return (stack==0) ? 0 : stack->fNode;
00367 }
00368 
00369 //______________________________________________________________________________
00370 void TBufferXML::ShiftStack(const char* errinfo)
00371 {
00372    // shift stack node to next
00373 
00374    TXMLStackObj* stack = dynamic_cast<TXMLStackObj*> (fStack.Last());
00375    if (stack) {
00376       fXML->ShiftToNext(stack->fNode);
00377       if (gDebug>4) Info("ShiftStack","%s to node %s", errinfo, fXML->GetNodeName(stack->fNode));
00378    }
00379 }
00380 
00381 //______________________________________________________________________________
00382 void TBufferXML::XmlWriteBlock(XMLNodePointer_t node)
00383 {
00384    // write binary data block from buffer to xml
00385    // this data can be produced only by direct call of TBuffer::WriteBuf() functions
00386 
00387    if ((node==0) || (Length()==0)) return;
00388 
00389    const char* src = Buffer();
00390    int srcSize = Length();
00391 
00392    char* fZipBuffer = 0;
00393 
00394    Int_t complevel = fCompressLevel;
00395 
00396    if ((Length() > 512) && (complevel>0)) {
00397       int zipBufferSize = Length();
00398       fZipBuffer = new char[zipBufferSize];
00399       int dataSize = Length();
00400       int compressedSize = 0;
00401       if (complevel>9) complevel = 9;
00402       R__zip(complevel, &dataSize, Buffer(), &zipBufferSize, fZipBuffer, &compressedSize);
00403       src = fZipBuffer;
00404       srcSize = compressedSize;
00405    }
00406 
00407    TString res;
00408    char sbuf[500];
00409    int block = 0;
00410    char* tgt = sbuf;
00411    int srcCnt = 0;
00412 
00413    while (srcCnt++<srcSize) {
00414       tgt+=sprintf(tgt, " %02x", (unsigned char) *src);
00415       src++;
00416       if (block++==100) {
00417          res += sbuf;
00418          block = 0;
00419          tgt = sbuf;
00420       }
00421    }
00422 
00423    if (block>0) res += sbuf;
00424 
00425    XMLNodePointer_t blocknode = fXML->NewChild(node, 0, xmlio::XmlBlock, res);
00426    fXML->NewIntAttr(blocknode, xmlio::Size, Length());
00427 
00428    if (fZipBuffer) {
00429       fXML->NewIntAttr(blocknode, xmlio::Zip, srcSize);
00430       delete[] fZipBuffer;
00431    }
00432 }
00433 
00434 //______________________________________________________________________________
00435 void TBufferXML::XmlReadBlock(XMLNodePointer_t blocknode)
00436 {
00437    // read binary block of data from xml
00438 
00439    if (blocknode==0) return;
00440 
00441    Int_t blockSize = fXML->GetIntAttr(blocknode, xmlio::Size);
00442    Bool_t blockCompressed = fXML->HasAttr(blocknode, xmlio::Zip);
00443    char* fUnzipBuffer = 0;
00444 
00445    if (gDebug>2)
00446       Info("XmlReadBlock","Block size = %d, Length = %d, Compressed = %d",
00447                            blockSize, Length(), blockCompressed);
00448 
00449    if (blockSize>BufferSize()) Expand(blockSize);
00450 
00451    char* tgt = Buffer();
00452    Int_t readSize = blockSize;
00453 
00454    TString content = fXML->GetNodeContent(blocknode);
00455 
00456    if (blockCompressed) {
00457       Int_t zipSize = fXML->GetIntAttr(blocknode, xmlio::Zip);
00458       fUnzipBuffer = new char[zipSize];
00459 
00460       tgt = fUnzipBuffer;
00461       readSize = zipSize;
00462    }
00463 
00464    char* ptr = (char*) content.Data();
00465 
00466    if (gDebug>3)
00467       Info("XmlReadBlock","Content %s", ptr);
00468 
00469    for (int i=0;i<readSize;i++) {
00470       while ((*ptr<48) || ((*ptr>57) && (*ptr<97)) || (*ptr>102)) ptr++;
00471 
00472       int b_hi = (*ptr>57) ? *ptr-87 : *ptr-48;
00473       ptr++;
00474       int b_lo = (*ptr>57) ? *ptr-87 : *ptr-48;
00475       ptr++;
00476 
00477       *tgt=b_hi*16+b_lo;
00478       tgt++;
00479 
00480       if (gDebug>4) Info("XmlReadBlock","    Buf[%d] = %d", i, b_hi*16+b_lo);
00481    }
00482 
00483    if (fUnzipBuffer) {
00484       int unzipRes = 0;
00485       R__unzip(&readSize, (unsigned char*) fUnzipBuffer, &blockSize,
00486                           (unsigned char*) Buffer(), &unzipRes);
00487       if (unzipRes!=blockSize)
00488          Error("XmlReadBlock", "Decompression error %d", unzipRes);
00489       else
00490          if (gDebug>2) Info("XmlReadBlock","Unzip ok");
00491       delete[] fUnzipBuffer;
00492    }
00493 }
00494 
00495 //______________________________________________________________________________
00496 Bool_t TBufferXML::ProcessPointer(const void* ptr, XMLNodePointer_t node)
00497 {
00498    // Add "ptr" attribute to node, if ptr is null or
00499    // if ptr is pointer on object, which is already saved in buffer
00500    // Automatically add "ref" attribute to node, where referenced object is stored
00501 
00502    if (node==0) return kFALSE;
00503 
00504    TString refvalue;
00505 
00506    if (ptr==0)
00507       refvalue = xmlio::Null;   //null
00508    else {
00509       if (fObjMap==0) return kFALSE;
00510 
00511       ULong_t hash = TString::Hash(&ptr, sizeof(void*));
00512 
00513       XMLNodePointer_t refnode = (XMLNodePointer_t) (Long_t)fObjMap->GetValue(hash, (Long_t) ptr);
00514       if (refnode==0) return kFALSE;
00515 
00516       if (fXML->HasAttr(refnode, xmlio::Ref))
00517          refvalue = fXML->GetAttr(refnode, xmlio::Ref);
00518       else {
00519          refvalue = xmlio::IdBase;
00520          if (XmlFile())
00521             refvalue += XmlFile()->GetNextRefCounter();
00522          else
00523             refvalue += GetNextRefCounter();
00524          fXML->NewAttr(refnode, 0, xmlio::Ref, refvalue.Data());
00525       }
00526    }
00527    if (refvalue.Length()>0) {
00528       fXML->NewAttr(node, 0, xmlio::Ptr, refvalue.Data());
00529       return kTRUE;
00530    }
00531 
00532    return kFALSE;
00533 }
00534 
00535 //______________________________________________________________________________
00536 void TBufferXML::RegisterPointer(const void* ptr, XMLNodePointer_t node)
00537 {
00538    // Register pair of object pointer and node, where this object is saved,
00539    // in object map
00540 
00541    if ((node==0) || (ptr==0)) return;
00542 
00543    ULong_t hash = TString::Hash(&ptr, sizeof(void*));
00544 
00545    if (fObjMap==0) fObjMap = new TExMap();
00546 
00547    if (fObjMap->GetValue(hash, (Long_t) ptr)==0)
00548       fObjMap->Add(hash, (Long_t) ptr, (Long_t) node);
00549 }
00550 
00551 //______________________________________________________________________________
00552 Bool_t TBufferXML::ExtractPointer(XMLNodePointer_t node, void* &ptr, TClass* &cl)
00553 {
00554    // Searches for "ptr" attribute and returns pointer to object and class,
00555    // if "ptr" attribute reference to read object
00556 
00557    cl = 0;
00558 
00559    if (!fXML->HasAttr(node,xmlio::Ptr)) return kFALSE;
00560 
00561    const char* ptrid = fXML->GetAttr(node, xmlio::Ptr);
00562 
00563    if (ptrid==0) return kFALSE;
00564 
00565    // null
00566    if (strcmp(ptrid, xmlio::Null)==0) {
00567       ptr = 0;
00568       return kTRUE;
00569    }
00570 
00571    if ((fIdArray==0) || (fObjMap==0)) return kFALSE;
00572 
00573    TNamed* obj = (TNamed*) fIdArray->FindObject(ptrid);
00574    if (obj) {
00575       ptr = (void*) (Long_t)fObjMap->GetValue((Long_t) fIdArray->IndexOf(obj));
00576       cl = TClass::GetClass(obj->GetTitle());
00577       return kTRUE;
00578    }
00579    return kFALSE;
00580 }
00581 
00582 //______________________________________________________________________________
00583 void TBufferXML::ExtractReference(XMLNodePointer_t node, const void* ptr, const TClass* cl)
00584 {
00585    // Analyse, if node has "ref" attribute and register it to object map
00586 
00587    if ((node==0) || (ptr==0)) return;
00588 
00589    const char* refid = fXML->GetAttr(node, xmlio::Ref);
00590 
00591    if (refid==0) return;
00592 
00593    if (fIdArray==0) {
00594       fIdArray = new TObjArray;
00595       fIdArray->SetOwner(kTRUE);
00596    }
00597    TNamed* nid = new TNamed(refid, cl->GetName());
00598    fIdArray->Add(nid);
00599 
00600    if (fObjMap==0) fObjMap = new TExMap();
00601 
00602    fObjMap->Add((Long_t) fIdArray->IndexOf(nid), (Long_t) ptr);
00603 
00604    if (gDebug>2)
00605       Info("ExtractReference","Find reference %s for object %p", refid, ptr);
00606 }
00607 
00608 //______________________________________________________________________________
00609 Bool_t TBufferXML::VerifyNode(XMLNodePointer_t node, const char* name, const char* errinfo)
00610 {
00611    // check, if node has specified name
00612 
00613    if ((name==0) || (node==0)) return kFALSE;
00614 
00615    if (strcmp(fXML->GetNodeName(node), name)!=0) {
00616       if (errinfo) {
00617          Error("VerifyNode","Reading XML file (%s). Get: %s, expects: %s",
00618                 errinfo, fXML->GetNodeName(node), name);
00619          fErrorFlag = 1;
00620       }
00621       return kFALSE;
00622    }
00623    return kTRUE;
00624 }
00625 
00626 //______________________________________________________________________________
00627 Bool_t TBufferXML::VerifyStackNode(const char* name, const char* errinfo)
00628 {
00629    // check, if stack node has specified name
00630 
00631    return VerifyNode(StackNode(), name, errinfo);
00632 }
00633 
00634 
00635 //______________________________________________________________________________
00636 Bool_t TBufferXML::VerifyAttr(XMLNodePointer_t node, const char* name, const char* value, const char* errinfo)
00637 {
00638    // checks, that attribute of specified name exists and has specified value
00639 
00640    if ((node==0) || (name==0) || (value==0)) return kFALSE;
00641    const char* cont = fXML->GetAttr(node, name);
00642    if (((cont==0) || (strcmp(cont, value)!=0))) {
00643       if  (errinfo) {
00644          Error("VerifyAttr","%s : attr %s = %s, expected: %s", errinfo, name, cont, value);
00645          fErrorFlag = 1;
00646       }
00647       return kFALSE;
00648    }
00649    return kTRUE;
00650 }
00651 
00652 //______________________________________________________________________________
00653 Bool_t TBufferXML::VerifyStackAttr(const char* name, const char* value, const char* errinfo)
00654 {
00655    // checks stack attribute
00656 
00657    return VerifyAttr(StackNode(), name, value, errinfo);
00658 }
00659 
00660 //______________________________________________________________________________
00661 XMLNodePointer_t TBufferXML::CreateItemNode(const char* name)
00662 {
00663    // create item node of specified name
00664 
00665    XMLNodePointer_t node = 0;
00666    if (GetXmlLayout()==kGeneralized) {
00667       node = fXML->NewChild(StackNode(), 0, xmlio::Item, 0);
00668       fXML->NewAttr(node, 0, xmlio::Name, name);
00669    } else
00670       node = fXML->NewChild(StackNode(), 0, name, 0);
00671    return node;
00672 }
00673 
00674 //______________________________________________________________________________
00675 Bool_t TBufferXML::VerifyItemNode(const char* name, const char* errinfo)
00676 {
00677    // checks, if stack node is item and has specified name
00678 
00679    Bool_t res = kTRUE;
00680    if (GetXmlLayout()==kGeneralized)
00681       res = VerifyStackNode(xmlio::Item, errinfo) &&
00682             VerifyStackAttr(xmlio::Name, name, errinfo);
00683    else
00684       res = VerifyStackNode(name, errinfo);
00685    return res;
00686 }
00687 
00688 //______________________________________________________________________________
00689 void TBufferXML::CreateElemNode(const TStreamerElement* elem)
00690 {
00691    // create xml node correspondent to TStreamerElement object
00692 
00693    XMLNodePointer_t elemnode = 0;
00694 
00695    const char* elemxmlname = XmlGetElementName(elem);
00696 
00697    if (GetXmlLayout()==kGeneralized) {
00698       elemnode = fXML->NewChild(StackNode(), 0, xmlio::Member, 0);
00699       fXML->NewAttr(elemnode, 0, xmlio::Name, elemxmlname);
00700    } else {
00701       // take namesapce for element only if it is not a base class or class name
00702       XMLNsPointer_t ns = Stack()->fClassNs;
00703       if ((elem->GetType()==TStreamerInfo::kBase)
00704            || ((elem->GetType()==TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName()))
00705            || ((elem->GetType()==TStreamerInfo::kTObject) && !strcmp(elem->GetName(), TObject::Class()->GetName()))
00706            || ((elem->GetType()==TStreamerInfo::kTString) && !strcmp(elem->GetName(), TString::Class()->GetName())))
00707          ns = 0;
00708 
00709       elemnode = fXML->NewChild(StackNode(), ns, elemxmlname, 0);
00710    }
00711 
00712    TXMLStackObj* curr = PushStack(elemnode);
00713    curr->fElem = (TStreamerElement*)elem;
00714 }
00715 
00716 //______________________________________________________________________________
00717 Bool_t TBufferXML::VerifyElemNode(const TStreamerElement* elem)
00718 {
00719    // Checks, if stack node correspond to TStreamerElement object
00720 
00721    const char* elemxmlname = XmlGetElementName(elem);
00722 
00723    if (GetXmlLayout()==kGeneralized) {
00724       if (!VerifyStackNode(xmlio::Member)) return kFALSE;
00725       if (!VerifyStackAttr(xmlio::Name, elemxmlname)) return kFALSE;
00726    } else {
00727       if (!VerifyStackNode(elemxmlname)) return kFALSE;
00728    }
00729 
00730    PerformPreProcessing(elem, StackNode());
00731 
00732    TXMLStackObj* curr = PushStack(StackNode()); // set pointer to first data inside element
00733    curr->fElem = (TStreamerElement*)elem;
00734    return kTRUE;
00735 }
00736 
00737 //______________________________________________________________________________
00738 XMLNodePointer_t TBufferXML::XmlWriteObject(const void* obj, const TClass* cl)
00739 {
00740    // Write object to buffer
00741    // If object was written before, only pointer will be stored
00742    // Return pointer to top xml node, representing object
00743 
00744    XMLNodePointer_t objnode = fXML->NewChild(StackNode(), 0, xmlio::Object, 0);
00745 
00746    if (!cl) obj = 0;
00747    if (ProcessPointer(obj, objnode)) return objnode;
00748 
00749    TString clname = XmlConvertClassName(cl->GetName());
00750 
00751    fXML->NewAttr(objnode, 0, xmlio::ObjClass, clname);
00752 
00753    RegisterPointer(obj, objnode);
00754 
00755    PushStack(objnode);
00756 
00757    ((TClass*)cl)->Streamer((void*)obj, *this);
00758 
00759    PopStack();
00760 
00761    if (gDebug>1)
00762       Info("XmlWriteObject","Done write for class: %s", cl ? cl->GetName() : "null");
00763 
00764    return objnode;
00765 }
00766 
00767 //______________________________________________________________________________
00768 void* TBufferXML::XmlReadObject(void* obj, TClass** cl)
00769 {
00770    // Read object from the buffer
00771 
00772    if (cl) *cl = 0;
00773 
00774    XMLNodePointer_t objnode = StackNode();
00775 
00776    if (fErrorFlag>0) return obj;
00777 
00778    if (objnode==0) return obj;
00779 
00780    if (!VerifyNode(objnode, xmlio::Object, "XmlReadObjectNew")) return obj;
00781 
00782    TClass* objClass = 0;
00783 
00784    if (ExtractPointer(objnode, obj, objClass)) {
00785       ShiftStack("readobjptr");
00786       if (cl) *cl = objClass;
00787       return obj;
00788    }
00789 
00790    TString clname = fXML->GetAttr(objnode, xmlio::ObjClass);
00791    objClass = XmlDefineClass(clname);
00792    if (objClass == TDirectory::Class()) objClass = TDirectoryFile::Class();
00793 
00794    if (objClass==0) {
00795       Error("XmlReadObject", "Cannot find class %s", clname.Data());
00796       ShiftStack("readobjerr");
00797       return obj;
00798    }
00799 
00800    if (gDebug>1)
00801       Info("XmlReadObject", "Reading object of class %s", clname.Data());
00802 
00803    if (obj==0) obj = objClass->New();
00804 
00805    ExtractReference(objnode, obj, objClass);
00806 
00807    PushStack(objnode);
00808 
00809    objClass->Streamer((void*)obj, *this);
00810 
00811    PopStack();
00812 
00813    ShiftStack("readobj");
00814 
00815    if (gDebug>1)
00816       Info("XmlReadObject", "Reading object of class %s done", clname.Data());
00817 
00818    if (cl) *cl = objClass;
00819 
00820    return obj;
00821 }
00822 
00823 //______________________________________________________________________________
00824 void TBufferXML::IncrementLevel(TVirtualStreamerInfo* info)
00825 {
00826    // Function is called from TStreamerInfo WriteBuffer and Readbuffer functions
00827    // and indent new level in xml structure.
00828    // This call indicates, that TStreamerInfo functions starts streaming
00829    // object data of correspondent class
00830 
00831    WorkWithClass((TStreamerInfo*)info);
00832 }
00833 
00834 //______________________________________________________________________________
00835 void  TBufferXML::WorkWithClass(TStreamerInfo* sinfo, const TClass* cl)
00836 {
00837    // Prepares buffer to stream data of specified class
00838 
00839    fCanUseCompact = kFALSE;
00840    fExpectedChain = kFALSE;
00841 
00842    if (sinfo!=0) cl = sinfo->GetClass();
00843 
00844    if (cl==0) return;
00845 
00846    TString clname = XmlConvertClassName(cl->GetName());
00847 
00848    if (gDebug>2) Info("IncrementLevel","Class: %s", clname.Data());
00849 
00850    Bool_t compressClassNode = fExpectedBaseClass==cl;
00851    fExpectedBaseClass = 0;
00852 
00853    TXMLStackObj* stack = Stack();
00854 
00855    if (IsWriting()) {
00856 
00857       XMLNodePointer_t classnode = 0;
00858       if (compressClassNode) {
00859          classnode = StackNode();
00860       } else {
00861          if (GetXmlLayout()==kGeneralized) {
00862             classnode = fXML->NewChild(StackNode(), 0, xmlio::Class, 0);
00863             fXML->NewAttr(classnode, 0, "name", clname);
00864          } else
00865             classnode = fXML->NewChild(StackNode(), 0, clname, 0);
00866          stack = PushStack(classnode);
00867       }
00868 
00869       if (fVersionBuf>=-1) {
00870          if (fVersionBuf == -1) fVersionBuf = 1;
00871          fXML->NewIntAttr(classnode, xmlio::ClassVersion, fVersionBuf);
00872          fVersionBuf = -111;
00873       }
00874 
00875       if (IsUseNamespaces() && (GetXmlLayout()!=kGeneralized))
00876          stack->fClassNs = fXML->NewNS(classnode, XmlClassNameSpaceRef(cl), clname);
00877 
00878    } else {
00879       if (!compressClassNode) {
00880          if (GetXmlLayout()==kGeneralized) {
00881             if (!VerifyStackNode(xmlio::Class, "StartInfo")) return;
00882             if (!VerifyStackAttr("name", clname, "StartInfo")) return;
00883          } else
00884             if (!VerifyStackNode(clname, "StartInfo")) return;
00885          stack = PushStack(StackNode());
00886       }
00887    }
00888 
00889    stack->fCompressedClassNode = compressClassNode;
00890    stack->fInfo = sinfo;
00891    stack->fIsStreamerInfo = kTRUE;
00892 }
00893 
00894 //______________________________________________________________________________
00895 void TBufferXML::DecrementLevel(TVirtualStreamerInfo* info)
00896 {
00897    // Function is called from TStreamerInfo WriteBuffer and Readbuffer functions
00898    // and decrease level in xml structure.
00899 
00900    CheckVersionBuf();
00901 
00902    fCanUseCompact = kFALSE;
00903    fExpectedChain = kFALSE;
00904 
00905    if (gDebug>2)
00906       Info("DecrementLevel","Class: %s", (info ? info->GetClass()->GetName() : "custom"));
00907 
00908    TXMLStackObj* stack = Stack();
00909 
00910    if (!stack->IsStreamerInfo()) {
00911       PerformPostProcessing();
00912       stack = PopStack();  // remove stack of last element
00913    }
00914 
00915    if (stack->fCompressedClassNode) {
00916       stack->fInfo = 0;
00917       stack->fIsStreamerInfo = kFALSE;
00918       stack->fCompressedClassNode = kFALSE;
00919    } else {
00920       PopStack();                       // back from data of stack info
00921       if (IsReading()) ShiftStack("declevel"); // shift to next element after streamer info
00922    }
00923 }
00924 
00925 //______________________________________________________________________________
00926 void TBufferXML::SetStreamerElementNumber(Int_t number)
00927 {
00928    // Function is called from TStreamerInfo WriteBuffer and Readbuffer functions
00929    // and add/verify next element of xml structure
00930    // This calls allows separate data, correspondent to one class member, from another
00931 
00932    WorkWithElement(0, number);
00933 }
00934 
00935 //______________________________________________________________________________
00936 void TBufferXML::WorkWithElement(TStreamerElement* elem, Int_t number)
00937 {
00938    //to be documented by Sergey
00939    CheckVersionBuf();
00940 
00941    fExpectedChain = kFALSE;
00942    fCanUseCompact = kFALSE;
00943    fExpectedBaseClass = 0;
00944 
00945    TXMLStackObj* stack = Stack();
00946    if (stack==0) {
00947       Error("SetStreamerElementNumber", "stack is empty");
00948       return;
00949    }
00950 
00951    if (!stack->IsStreamerInfo()) {  // this is not a first element
00952       PerformPostProcessing();
00953       PopStack();           // go level back
00954       if (IsReading()) ShiftStack("startelem");   // shift to next element, only for reading
00955       stack = dynamic_cast<TXMLStackObj*> (fStack.Last());
00956    }
00957 
00958    if (stack==0) {
00959       Error("SetStreamerElementNumber", "Lost of stack");
00960       return;
00961    }
00962 
00963    Int_t comp_type = 0;
00964 
00965    if ((number>=0) && (elem==0)) {
00966 
00967       TStreamerInfo* info = stack->fInfo;
00968       if (!stack->IsStreamerInfo()) {
00969          Error("SetStreamerElementNumber", "Problem in Inc/Dec level");
00970          return;
00971       }
00972 
00973       comp_type = info->GetTypes()[number];
00974 
00975       elem = info->GetStreamerElementReal(number, 0);
00976    } else
00977       comp_type = elem->GetType();
00978 
00979 
00980    if (elem==0) {
00981       Error("SetStreamerElementNumber", "streamer info returns elem = 0");
00982       return;
00983    }
00984 
00985    if (gDebug>4) Info("SetStreamerElementNumber", "    Next element %s", elem->GetName());
00986 
00987    Bool_t isBasicType = (elem->GetType()>0) && (elem->GetType()<20);
00988 
00989    fExpectedChain = isBasicType && (comp_type - elem->GetType() == TStreamerInfo::kOffsetL);
00990 
00991    if (fExpectedChain && (gDebug>3))
00992       Info("SetStreamerElementNumber",
00993            "    Expects chain for elem %s number %d",
00994             elem->GetName(), number);
00995 
00996    fCanUseCompact = isBasicType && ((elem->GetType()==comp_type) ||
00997                                     (elem->GetType()==comp_type-TStreamerInfo::kConv) ||
00998                                     (elem->GetType()==comp_type-TStreamerInfo::kSkip));
00999 
01000 
01001    if ((elem->GetType()==TStreamerInfo::kBase) ||
01002        ((elem->GetType()==TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())))
01003       fExpectedBaseClass = elem->GetClassPointer();
01004 
01005    if (fExpectedBaseClass && (gDebug>3))
01006       Info("SetStreamerElementNumber",
01007            "   Expects base class %s with standard streamer",
01008                fExpectedBaseClass->GetName());
01009 
01010    if (IsWriting()) {
01011       CreateElemNode(elem);
01012    } else {
01013       if (!VerifyElemNode(elem)) return;
01014    }
01015 
01016    stack = Stack();
01017    stack->fElemNumber = number;
01018    stack->fIsElemOwner = (number<0);
01019 }
01020 
01021 //______________________________________________________________________________
01022 void TBufferXML::ClassBegin(const TClass* cl, Version_t)
01023 {
01024    //to be documented by Sergey
01025    WorkWithClass(0, cl);
01026 }
01027 
01028 //______________________________________________________________________________
01029 void TBufferXML::ClassEnd(const TClass*)
01030 {
01031    //to be documented by Sergey
01032    DecrementLevel(0);
01033 }
01034 
01035 //______________________________________________________________________________
01036 void TBufferXML::ClassMember(const char* name, const char* typeName, Int_t arrsize1, Int_t arrsize2)
01037 {
01038    //to be documented by Sergey
01039    if (typeName==0) typeName = name;
01040 
01041    if ((name==0) || (strlen(name)==0)) {
01042       Error("ClassMember","Invalid member name");
01043       fErrorFlag = 1;
01044       return;
01045    }
01046 
01047    TString tname = typeName;
01048 
01049    Int_t typ_id = -1;
01050 
01051    if (strcmp(typeName,"raw:data")==0)
01052       typ_id = TStreamerInfo::kMissing;
01053 
01054    if (typ_id<0) {
01055       TDataType *dt = gROOT->GetType(typeName);
01056       if (dt!=0)
01057          if ((dt->GetType()>0) && (dt->GetType()<20))
01058             typ_id = dt->GetType();
01059    }
01060 
01061    if (typ_id<0)
01062       if (strcmp(name, typeName)==0) {
01063          TClass* cl = TClass::GetClass(tname.Data());
01064          if (cl!=0) typ_id = TStreamerInfo::kBase;
01065       }
01066 
01067    if (typ_id<0) {
01068       Bool_t isptr = kFALSE;
01069       if (tname[tname.Length()-1]=='*') {
01070          tname.Resize(tname.Length()-1);
01071          isptr = kTRUE;
01072       }
01073       TClass* cl = TClass::GetClass(tname.Data());
01074       if (cl==0) {
01075          Error("ClassMember","Invalid class specifier %s", typeName);
01076          fErrorFlag = 1;
01077          return;
01078       }
01079 
01080       if (cl->IsTObject())
01081          typ_id = isptr ? TStreamerInfo::kObjectp : TStreamerInfo::kObject;
01082       else
01083          typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
01084 
01085       if ((cl==TString::Class()) && !isptr)
01086          typ_id = TStreamerInfo::kTString;
01087    }
01088 
01089    TStreamerElement* elem = 0;
01090 
01091    if (typ_id == TStreamerInfo::kMissing) {
01092       elem = new TStreamerElement(name,"title",0, typ_id, "raw:data");
01093    } else
01094 
01095 
01096    if (typ_id==TStreamerInfo::kBase) {
01097       TClass* cl = TClass::GetClass(tname.Data());
01098       if (cl!=0) {
01099          TStreamerBase* b = new TStreamerBase(tname.Data(), "title", 0);
01100          b->SetBaseVersion(cl->GetClassVersion());
01101          elem = b;
01102       }
01103    } else
01104 
01105    if ((typ_id>0) && (typ_id<20)) {
01106       elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
01107    } else
01108 
01109    if ((typ_id==TStreamerInfo::kObject) ||
01110        (typ_id==TStreamerInfo::kTObject) ||
01111        (typ_id==TStreamerInfo::kTNamed)) {
01112       elem = new TStreamerObject(name, "title", 0, tname.Data());
01113    } else
01114 
01115    if (typ_id==TStreamerInfo::kObjectp) {
01116       elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
01117    } else
01118 
01119    if (typ_id==TStreamerInfo::kAny) {
01120       elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
01121    } else
01122 
01123    if (typ_id==TStreamerInfo::kAnyp) {
01124       elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
01125    } else
01126 
01127    if (typ_id==TStreamerInfo::kTString) {
01128       elem = new TStreamerString(name, "title", 0);
01129    }
01130 
01131    if (elem==0) {
01132       Error("ClassMember","Invalid combination name = %s type = %s", name, typeName);
01133       fErrorFlag = 1;
01134       return;
01135    }
01136 
01137    if (arrsize1>0) {
01138       elem->SetArrayDim(arrsize2>0 ? 2 : 1);
01139       elem->SetMaxIndex(0, arrsize1);
01140       if (arrsize2>0)
01141          elem->SetMaxIndex(1, arrsize2);
01142    }
01143 
01144    // we indicate that there is no streamerinfo
01145    WorkWithElement(elem, -1);
01146 }
01147 
01148 //______________________________________________________________________________
01149 void TBufferXML::PerformPostProcessing()
01150 {
01151    // Function is converts TObject and TString structures to more compact representation
01152 
01153    if (GetXmlLayout()==kGeneralized) return;
01154 
01155    const TStreamerElement* elem = Stack()->fElem;
01156    XMLNodePointer_t elemnode = IsWriting() ? Stack()->fNode : Stack(1)->fNode;
01157 
01158    if ((elem==0) || (elemnode==0)) return;
01159 
01160    if (elem->GetType()==TStreamerInfo::kTString) {
01161 
01162       XMLNodePointer_t node = fXML->GetChild(elemnode);
01163       fXML->SkipEmpty(node);
01164 
01165       XMLNodePointer_t nodecharstar = 0;
01166       XMLNodePointer_t nodeuchar = 0;
01167       XMLNodePointer_t nodeint = 0;
01168 
01169       while (node!=0) {
01170          const char* name = fXML->GetNodeName(node);
01171          if (strcmp(name, xmlio::UChar)==0) {
01172             if (nodeuchar) return;
01173             nodeuchar = node;
01174          } else
01175          if (strcmp(name, xmlio::Int)==0) {
01176             if (nodeint) return;
01177             nodeint = node;
01178          } else
01179          if (strcmp(name, xmlio::CharStar)==0) {
01180             if (nodecharstar!=0) return;
01181             nodecharstar = node;
01182          } else return; // can not be something else
01183          fXML->ShiftToNext(node);
01184       }
01185 
01186       if (nodeuchar==0) return;
01187 
01188       TString str;
01189       if (nodecharstar!=0)
01190          str = fXML->GetAttr(nodecharstar, xmlio::v);
01191       fXML->NewAttr(elemnode, 0, "str", str);
01192 
01193       fXML->UnlinkFreeNode(nodeuchar);
01194       fXML->UnlinkFreeNode(nodeint);
01195       fXML->UnlinkFreeNode(nodecharstar);
01196    } else
01197    if (elem->GetType()==TStreamerInfo::kTObject) {
01198       XMLNodePointer_t node = fXML->GetChild(elemnode);
01199       fXML->SkipEmpty(node);
01200 
01201       XMLNodePointer_t vnode = 0;
01202       XMLNodePointer_t idnode = 0;
01203       XMLNodePointer_t bitsnode = 0;
01204       XMLNodePointer_t prnode = 0;
01205       while (node!=0) {
01206          const char* name = fXML->GetNodeName(node);
01207 
01208          if (strcmp(name, xmlio::OnlyVersion)==0) {
01209             if (vnode) return;
01210             vnode = node;
01211          } else
01212          if (strcmp(name, xmlio::UInt)==0) {
01213             if (idnode==0) idnode = node; else
01214             if (bitsnode==0) bitsnode = node; else return;
01215          } else
01216          if (strcmp(name, xmlio::UShort)==0) {
01217             if (prnode) return;
01218             prnode = node;
01219          } else return;
01220          fXML->ShiftToNext(node);
01221       }
01222 
01223       if ((vnode==0) || (idnode==0) || (bitsnode==0)) return;
01224 
01225       TString str = fXML->GetAttr(idnode,xmlio::v);
01226       fXML->NewAttr(elemnode, 0, "fUniqueID", str);
01227 
01228       str = fXML->GetAttr(bitsnode, xmlio::v);
01229       UInt_t bits;
01230       sscanf(str.Data(),"%u", &bits);
01231 
01232       char sbuf[20];
01233       snprintf(sbuf, sizeof(sbuf), "%x",bits);
01234       fXML->NewAttr(elemnode, 0, "fBits", sbuf);
01235 
01236       if (prnode!=0) {
01237          str = fXML->GetAttr(prnode,xmlio::v);
01238          fXML->NewAttr(elemnode, 0, "fProcessID", str);
01239       }
01240 
01241       fXML->UnlinkFreeNode(vnode);
01242       fXML->UnlinkFreeNode(idnode);
01243       fXML->UnlinkFreeNode(bitsnode);
01244       fXML->UnlinkFreeNode(prnode);
01245    }
01246 }
01247 
01248 //______________________________________________________________________________
01249 void TBufferXML::PerformPreProcessing(const TStreamerElement* elem, XMLNodePointer_t elemnode)
01250 {
01251    // Function is unpack TObject and TString structures to be able read
01252    // them from custom streamers of this objects
01253 
01254    if (GetXmlLayout()==kGeneralized) return;
01255    if ((elem==0) || (elemnode==0)) return;
01256 
01257    if (elem->GetType()==TStreamerInfo::kTString) {
01258 
01259       if (!fXML->HasAttr(elemnode,"str")) return;
01260       TString str = fXML->GetAttr(elemnode, "str");
01261       fXML->FreeAttr(elemnode, "str");
01262       Int_t len = str.Length();
01263 
01264       XMLNodePointer_t ucharnode = fXML->NewChild(elemnode, 0, xmlio::UChar,0);
01265 
01266       char sbuf[20];
01267       snprintf(sbuf, sizeof(sbuf), "%d", len);
01268       if (len<255)
01269          fXML->NewAttr(ucharnode,0,xmlio::v,sbuf);
01270       else {
01271          fXML->NewAttr(ucharnode,0,xmlio::v,"255");
01272          XMLNodePointer_t intnode = fXML->NewChild(elemnode, 0, xmlio::Int, 0);
01273          fXML->NewAttr(intnode, 0, xmlio::v, sbuf);
01274       }
01275       if (len>0) {
01276          XMLNodePointer_t node = fXML->NewChild(elemnode, 0, xmlio::CharStar, 0);
01277          fXML->NewAttr(node, 0, xmlio::v, str);
01278       }
01279    } else
01280    if (elem->GetType()==TStreamerInfo::kTObject) {
01281       if (!fXML->HasAttr(elemnode, "fUniqueID")) return;
01282       if (!fXML->HasAttr(elemnode, "fBits")) return;
01283 
01284       TString idstr = fXML->GetAttr(elemnode, "fUniqueID");
01285       TString bitsstr = fXML->GetAttr(elemnode, "fBits");
01286       TString prstr = fXML->GetAttr(elemnode, "fProcessID");
01287 
01288       fXML->FreeAttr(elemnode, "fUniqueID");
01289       fXML->FreeAttr(elemnode, "fBits");
01290       fXML->FreeAttr(elemnode, "fProcessID");
01291 
01292       XMLNodePointer_t node = fXML->NewChild(elemnode, 0, xmlio::OnlyVersion, 0);
01293       fXML->NewAttr(node, 0, xmlio::v, "1");
01294 
01295       node = fXML->NewChild(elemnode, 0, xmlio::UInt, 0);
01296       fXML->NewAttr(node, 0, xmlio::v, idstr);
01297 
01298       UInt_t bits;
01299       sscanf(bitsstr.Data(),"%x", &bits);
01300       char sbuf[20];
01301       snprintf(sbuf, sizeof(sbuf), "%u", bits);
01302 
01303       node = fXML->NewChild(elemnode, 0, xmlio::UInt, 0);
01304       fXML->NewAttr(node, 0, xmlio::v, sbuf);
01305 
01306       if (prstr.Length()>0) {
01307          node = fXML->NewChild(elemnode, 0, xmlio::UShort, 0);
01308          fXML->NewAttr(node, 0, xmlio::v, prstr.Data());
01309       }
01310    }
01311 }
01312 
01313 //______________________________________________________________________________
01314 void TBufferXML::BeforeIOoperation()
01315 {
01316   // Function is called before any IO operation of TBuffer
01317   // Now is used to store version value if no proper calls are discovered
01318 
01319    CheckVersionBuf();
01320 }
01321 
01322 //______________________________________________________________________________
01323 TClass* TBufferXML::ReadClass(const TClass*, UInt_t*)
01324 {
01325    // suppressed function of TBuffer
01326 
01327    return 0;
01328 }
01329 
01330 //______________________________________________________________________________
01331 void TBufferXML::WriteClass(const TClass*)
01332 {
01333    // suppressed function of TBuffer
01334 
01335 }
01336 
01337 //______________________________________________________________________________
01338 Int_t TBufferXML::CheckByteCount(UInt_t /*r_s */, UInt_t /*r_c*/, const TClass* /*cl*/)
01339 {
01340    // suppressed function of TBuffer
01341 
01342    return 0;
01343 }
01344 
01345 //______________________________________________________________________________
01346 Int_t  TBufferXML::CheckByteCount(UInt_t, UInt_t, const char*)
01347 {
01348    // suppressed function of TBuffer
01349 
01350    return 0;
01351 }
01352 
01353 //______________________________________________________________________________
01354 void TBufferXML::SetByteCount(UInt_t, Bool_t)
01355 {
01356    // suppressed function of TBuffer
01357 
01358 }
01359 
01360 //______________________________________________________________________________
01361 void TBufferXML::SkipVersion(const TClass *cl)
01362 {
01363    // Skip class version from I/O buffer.
01364    ReadVersion(0,0,cl);
01365 }
01366    
01367 //______________________________________________________________________________
01368 Version_t TBufferXML::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass * /*cl*/)
01369 {
01370    // read version value from buffer
01371 
01372    BeforeIOoperation();
01373 
01374    Version_t res = 0;
01375 
01376    if (start) *start = 0;
01377    if (bcnt) *bcnt = 0;
01378 
01379    if (VerifyItemNode(xmlio::OnlyVersion)) {
01380       res = AtoI(XmlReadValue(xmlio::OnlyVersion));
01381    } else
01382    if ((fExpectedBaseClass!=0) && (fXML->HasAttr(Stack(1)->fNode, xmlio::ClassVersion))) {
01383       res = fXML->GetIntAttr(Stack(1)->fNode, xmlio::ClassVersion);
01384    } else
01385    if (fXML->HasAttr(StackNode(), xmlio::ClassVersion)) {
01386       res = fXML->GetIntAttr(StackNode(), xmlio::ClassVersion);
01387    } else {
01388       Error("ReadVersion", "No correspondent tags to read version");;
01389       fErrorFlag = 1;
01390    }
01391 
01392    if (gDebug>2) Info("ReadVersion","Version = %d", res);
01393 
01394    return res;
01395 }
01396 
01397 //______________________________________________________________________________
01398 void TBufferXML::CheckVersionBuf()
01399 {
01400    // checks buffer, filled by WriteVersion
01401    // if next data is arriving, version should be stored in buffer
01402 
01403    if (IsWriting() && (fVersionBuf>=-100)) {
01404       char sbuf[20];
01405       snprintf(sbuf, sizeof(sbuf), "%d", fVersionBuf);
01406       XmlWriteValue(sbuf, xmlio::OnlyVersion);
01407       fVersionBuf = -111;
01408    }
01409 }
01410 
01411 //______________________________________________________________________________
01412 UInt_t TBufferXML::WriteVersion(const TClass *cl, Bool_t /* useBcnt */)
01413 {
01414    // Copies class version to buffer, but not writes it to xml
01415    // Version will be written with next I/O operation or
01416    // will be added as attribute of class tag, created by IncrementLevel call
01417 
01418    BeforeIOoperation();
01419 
01420    if (fExpectedBaseClass!=cl)
01421       fExpectedBaseClass = 0;
01422 
01423    fVersionBuf = cl->GetClassVersion();
01424 
01425    if (gDebug>2)
01426       Info("WriteVersion", "Class: %s, version = %d",
01427            cl->GetName(), fVersionBuf);
01428 
01429    return 0;
01430 }
01431 
01432 //______________________________________________________________________________
01433 void* TBufferXML::ReadObjectAny(const TClass*)
01434 {
01435    // Read object from buffer. Only used from TBuffer
01436 
01437    BeforeIOoperation();
01438    if (gDebug>2)
01439       Info("ReadObjectAny","From node %s", fXML->GetNodeName(StackNode()));
01440    void* res = XmlReadObject(0);
01441    return res;
01442 }
01443 
01444 //______________________________________________________________________________
01445 void TBufferXML::SkipObjectAny()
01446 {
01447    // Skip any kind of object from buffer
01448    // Actually skip only one node on current level of xml structure
01449 
01450    ShiftStack("skipobjectany");                                          \
01451 }
01452 
01453 //______________________________________________________________________________
01454 void TBufferXML::WriteObjectClass(const void *actualObjStart, const TClass *actualClass)
01455 {
01456    // Write object to buffer. Only used from TBuffer
01457 
01458    BeforeIOoperation();
01459    if (gDebug>2)
01460       Info("WriteObject","Class %s", (actualClass ? actualClass->GetName() : " null"));
01461    XmlWriteObject(actualObjStart, actualClass);
01462 }
01463 
01464 // Macro to read content of uncompressed array
01465 #define TXMLReadArrayNoncompress(vname) \
01466 {                                       \
01467    for(Int_t indx=0;indx<n;indx++)      \
01468      XmlReadBasic(vname[indx]);         \
01469 }
01470 
01471 // macro to read content of array with compression
01472 #define TXMLReadArrayContent(vname, arrsize)               \
01473 {                                                          \
01474    Int_t indx = 0;                                         \
01475    while(indx<arrsize) {                                   \
01476      Int_t cnt = 1;                                        \
01477      if (fXML->HasAttr(StackNode(), xmlio::cnt))         \
01478         cnt = fXML->GetIntAttr(StackNode(), xmlio::cnt); \
01479      XmlReadBasic(vname[indx]);                            \
01480      Int_t curr = indx; indx++;                            \
01481      while(cnt>1) {                                        \
01482        vname[indx] = vname[curr];                          \
01483        cnt--; indx++;                                      \
01484      }                                                     \
01485    }                                                       \
01486 }
01487 
01488 // macro to read array, which include size attribute
01489 #define TBufferXML_ReadArray(tname, vname)                    \
01490 {                                                             \
01491    BeforeIOoperation();                                       \
01492    if (!VerifyItemNode(xmlio::Array,"ReadArray")) return 0; \
01493    Int_t n = fXML->GetIntAttr(StackNode(), xmlio::Size);    \
01494    if (n<=0) return 0;                                        \
01495    if (!vname) vname = new tname[n];                          \
01496    PushStack(StackNode());                                    \
01497    TXMLReadArrayContent(vname, n);                            \
01498    PopStack();                                                \
01499    ShiftStack("readarr");                                     \
01500    return n;                                                  \
01501 }
01502 
01503 //______________________________________________________________________________
01504 void TBufferXML::ReadFloat16 (Float_t *f, TStreamerElement * /*ele*/)
01505 {
01506    // read a Float16_t from the buffer
01507    BeforeIOoperation();
01508    XmlReadBasic(*f);
01509 }
01510 
01511 //______________________________________________________________________________
01512 void TBufferXML::ReadDouble32 (Double_t *d, TStreamerElement * /*ele*/)
01513 {
01514    // read a Double32_t from the buffer
01515    BeforeIOoperation();
01516    XmlReadBasic(*d);
01517 }
01518 
01519 //______________________________________________________________________________
01520 void TBufferXML::ReadWithFactor(Float_t *ptr, Double_t /* factor */, Double_t /* minvalue */)
01521 {
01522    // Read a Double32_t from the buffer when the factor and minimun value have been specified
01523    // see comments about Double32_t encoding at TBufferFile::WriteDouble32().
01524    // Currently TBufferXML does not optimize space in this case.
01525    
01526    BeforeIOoperation();
01527    XmlReadBasic(*ptr);
01528 }
01529 
01530 //______________________________________________________________________________
01531 void TBufferXML::ReadWithNbits(Float_t *ptr, Int_t /* nbits */) 
01532 {
01533    // Read a Float16_t from the buffer when the number of bits is specified (explicitly or not)
01534    // see comments about Float16_t encoding at TBufferFile::WriteFloat16().
01535    // Currently TBufferXML does not optimize space in this case.
01536    
01537    BeforeIOoperation();
01538    XmlReadBasic(*ptr);
01539 }
01540 
01541 //______________________________________________________________________________
01542 void TBufferXML::ReadWithFactor(Double_t *ptr, Double_t /* factor */, Double_t /* minvalue */) 
01543 {
01544    // Read a Double32_t from the buffer when the factor and minimun value have been specified
01545    // see comments about Double32_t encoding at TBufferFile::WriteDouble32().   
01546    // Currently TBufferXML does not optimize space in this case.
01547    
01548    BeforeIOoperation();
01549    XmlReadBasic(*ptr);
01550 }
01551 
01552 //______________________________________________________________________________
01553 void TBufferXML::ReadWithNbits(Double_t *ptr, Int_t /* nbits */) 
01554 {
01555    // Read a Double32_t from the buffer when the number of bits is specified (explicitly or not)
01556    // see comments about Double32_t encoding at TBufferFile::WriteDouble32().   
01557    // Currently TBufferXML does not optimize space in this case.
01558    
01559    BeforeIOoperation();
01560    XmlReadBasic(*ptr);
01561 }
01562 
01563 //______________________________________________________________________________
01564 void TBufferXML::WriteFloat16 (Float_t *f, TStreamerElement * /*ele*/)
01565 {
01566    // write a Float16_t to the buffer
01567    BeforeIOoperation();
01568    XmlWriteBasic(*f);
01569 }
01570 
01571 //______________________________________________________________________________
01572 void TBufferXML::WriteDouble32 (Double_t *d, TStreamerElement * /*ele*/)
01573 {
01574    // write a Double32_t to the buffer
01575    BeforeIOoperation();
01576    XmlWriteBasic(*d);
01577 }
01578 
01579 //______________________________________________________________________________
01580 Int_t TBufferXML::ReadArray(Bool_t    *&b)
01581 {
01582    // Read array of Bool_t from buffer
01583 
01584    TBufferXML_ReadArray(Bool_t,b);
01585 }
01586 
01587 //______________________________________________________________________________
01588 Int_t TBufferXML::ReadArray(Char_t    *&c)
01589 {
01590    // Read array of Char_t from buffer
01591 
01592    TBufferXML_ReadArray(Char_t,c);
01593 }
01594 
01595 //______________________________________________________________________________
01596 Int_t TBufferXML::ReadArray(UChar_t   *&c)
01597 {
01598    // Read array of UChar_t from buffer
01599 
01600    TBufferXML_ReadArray(UChar_t,c);
01601 }
01602 
01603 //______________________________________________________________________________
01604 Int_t TBufferXML::ReadArray(Short_t   *&h)
01605 {
01606    // Read array of Short_t from buffer
01607 
01608    TBufferXML_ReadArray(Short_t,h);
01609 }
01610 
01611 //______________________________________________________________________________
01612 Int_t TBufferXML::ReadArray(UShort_t  *&h)
01613 {
01614    // Read array of UShort_t from buffer
01615 
01616    TBufferXML_ReadArray(UShort_t,h);
01617 }
01618 
01619 //______________________________________________________________________________
01620 Int_t TBufferXML::ReadArray(Int_t     *&i)
01621 {
01622    // Read array of Int_t from buffer
01623 
01624    TBufferXML_ReadArray(Int_t,i);
01625 }
01626 
01627 //______________________________________________________________________________
01628 Int_t TBufferXML::ReadArray(UInt_t    *&i)
01629 {
01630    // Read array of UInt_t from buffer
01631 
01632    TBufferXML_ReadArray(UInt_t,i);
01633 }
01634 
01635 //______________________________________________________________________________
01636 Int_t TBufferXML::ReadArray(Long_t    *&l)
01637 {
01638    // Read array of Long_t from buffer
01639 
01640    TBufferXML_ReadArray(Long_t,l);
01641 }
01642 
01643 //______________________________________________________________________________
01644 Int_t TBufferXML::ReadArray(ULong_t   *&l)
01645 {
01646    // Read array of ULong_t from buffer
01647 
01648    TBufferXML_ReadArray(ULong_t,l);
01649 }
01650 
01651 //______________________________________________________________________________
01652 Int_t TBufferXML::ReadArray(Long64_t  *&l)
01653 {
01654    // Read array of Long64_t from buffer
01655 
01656    TBufferXML_ReadArray(Long64_t,l);
01657 }
01658 
01659 //______________________________________________________________________________
01660 Int_t TBufferXML::ReadArray(ULong64_t *&l)
01661 {
01662    // Read array of ULong64_t from buffer
01663 
01664    TBufferXML_ReadArray(ULong64_t,l);
01665 }
01666 
01667 //______________________________________________________________________________
01668 Int_t TBufferXML::ReadArray(Float_t   *&f)
01669 {
01670    // Read array of Float_t from buffer
01671 
01672    TBufferXML_ReadArray(Float_t,f);
01673 }
01674 
01675 //______________________________________________________________________________
01676 Int_t TBufferXML::ReadArray(Double_t  *&d)
01677 {
01678    // Read array of Double_t from buffer
01679 
01680    TBufferXML_ReadArray(Double_t,d);
01681 }
01682 
01683 //______________________________________________________________________________
01684 Int_t TBufferXML::ReadArrayFloat16(Float_t  *&f, TStreamerElement * /*ele*/)
01685 {
01686    // Read array of Float16_t from buffer
01687 
01688    TBufferXML_ReadArray(Float_t,f);
01689 }
01690 
01691 //______________________________________________________________________________
01692 Int_t TBufferXML::ReadArrayDouble32(Double_t  *&d, TStreamerElement * /*ele*/)
01693 {
01694    // Read array of Double32_t from buffer
01695 
01696    TBufferXML_ReadArray(Double_t,d);
01697 }
01698 
01699 // macro to read array from xml buffer
01700 #define TBufferXML_ReadStaticArray(vname)                           \
01701 {                                                                   \
01702    BeforeIOoperation();                                             \
01703    if (!VerifyItemNode(xmlio::Array,"ReadStaticArray")) return 0; \
01704    Int_t n = fXML->GetIntAttr(StackNode(), xmlio::Size);          \
01705    if (n<=0) return 0;                                              \
01706    if (!vname) return 0;                                            \
01707    PushStack(StackNode());                                          \
01708    TXMLReadArrayContent(vname, n);                                  \
01709    PopStack();                                                      \
01710    ShiftStack("readstatarr");                                       \
01711    return n;                                                        \
01712 }
01713 
01714 //______________________________________________________________________________
01715 Int_t TBufferXML::ReadStaticArray(Bool_t    *b)
01716 {
01717    // Read array of Bool_t from buffer
01718 
01719    TBufferXML_ReadStaticArray(b);
01720 }
01721 
01722 //______________________________________________________________________________
01723 Int_t TBufferXML::ReadStaticArray(Char_t    *c)
01724 {
01725    // Read array of Char_t from buffer
01726 
01727    TBufferXML_ReadStaticArray(c);
01728 }
01729 
01730 //______________________________________________________________________________
01731 Int_t TBufferXML::ReadStaticArray(UChar_t   *c)
01732 {
01733    // Read array of UChar_t from buffer
01734 
01735    TBufferXML_ReadStaticArray(c);
01736 }
01737 
01738 //______________________________________________________________________________
01739 Int_t TBufferXML::ReadStaticArray(Short_t   *h)
01740 {
01741    // Read array of Short_t from buffer
01742 
01743    TBufferXML_ReadStaticArray(h);
01744 }
01745 
01746 //______________________________________________________________________________
01747 Int_t TBufferXML::ReadStaticArray(UShort_t  *h)
01748 {
01749    // Read array of UShort_t from buffer
01750 
01751    TBufferXML_ReadStaticArray(h);
01752 }
01753 
01754 //______________________________________________________________________________
01755 Int_t TBufferXML::ReadStaticArray(Int_t     *i)
01756 {
01757    // Read array of Int_t from buffer
01758 
01759    TBufferXML_ReadStaticArray(i);
01760 }
01761 
01762 //______________________________________________________________________________
01763 Int_t TBufferXML::ReadStaticArray(UInt_t    *i)
01764 {
01765    // Read array of UInt_t from buffer
01766 
01767    TBufferXML_ReadStaticArray(i);
01768 }
01769 
01770 //______________________________________________________________________________
01771 Int_t TBufferXML::ReadStaticArray(Long_t    *l)
01772 {
01773    // Read array of Long_t from buffer
01774 
01775    TBufferXML_ReadStaticArray(l);
01776 }
01777 
01778 //______________________________________________________________________________
01779 Int_t TBufferXML::ReadStaticArray(ULong_t   *l)
01780 {
01781    // Read array of ULong_t from buffer
01782 
01783    TBufferXML_ReadStaticArray(l);
01784 }
01785 
01786 //______________________________________________________________________________
01787 Int_t TBufferXML::ReadStaticArray(Long64_t  *l)
01788 {
01789    // Read array of Long64_t from buffer
01790 
01791    TBufferXML_ReadStaticArray(l);
01792 }
01793 
01794 //______________________________________________________________________________
01795 Int_t TBufferXML::ReadStaticArray(ULong64_t *l)
01796 {
01797    // Read array of ULong64_t from buffer
01798 
01799    TBufferXML_ReadStaticArray(l);
01800 }
01801 
01802 //______________________________________________________________________________
01803 Int_t TBufferXML::ReadStaticArray(Float_t   *f)
01804 {
01805    // Read array of Float_t from buffer
01806 
01807    TBufferXML_ReadStaticArray(f);
01808 }
01809 
01810 //______________________________________________________________________________
01811 Int_t TBufferXML::ReadStaticArray(Double_t  *d)
01812 {
01813    // Read array of Double_t from buffer
01814 
01815    TBufferXML_ReadStaticArray(d);
01816 }
01817 
01818 //______________________________________________________________________________
01819 Int_t TBufferXML::ReadStaticArrayFloat16(Float_t  *f, TStreamerElement * /*ele*/)
01820 {
01821    // Read array of Float16_t from buffer
01822 
01823    TBufferXML_ReadStaticArray(f);
01824 }
01825 
01826 //______________________________________________________________________________
01827 Int_t TBufferXML::ReadStaticArrayDouble32(Double_t  *d, TStreamerElement * /*ele*/)
01828 {
01829    // Read array of Double32_t from buffer
01830 
01831    TBufferXML_ReadStaticArray(d);
01832 }
01833 
01834 // macro to read content of array, which not include size of array
01835 // macro also treat situation, when instead of one single array chain
01836 // of several elements should be produced
01837 #define TBufferXML_ReadFastArray(vname)                                   \
01838 {                                                                         \
01839    BeforeIOoperation();                                                   \
01840    if (n<=0) return;                                                      \
01841    TStreamerElement* elem = Stack(0)->fElem;                              \
01842    if ((elem!=0) && (elem->GetType()>TStreamerInfo::kOffsetL) &&          \
01843        (elem->GetType()<TStreamerInfo::kOffsetP) &&                       \
01844        (elem->GetArrayLength()!=n)) fExpectedChain = kTRUE;               \
01845    if (fExpectedChain) {                                                  \
01846       fExpectedChain = kFALSE;                                            \
01847       Int_t startnumber = Stack(0)->fElemNumber;                          \
01848       TStreamerInfo* info = Stack(1)->fInfo;                              \
01849       Int_t number = 0;                                                   \
01850       Int_t index = 0;                                                    \
01851       while (index<n) {                                                   \
01852         elem = info->GetStreamerElementReal(startnumber, number++);       \
01853         if (elem->GetType()<TStreamerInfo::kOffsetL) {                    \
01854            if (index>0) { PopStack(); ShiftStack("chainreader"); VerifyElemNode(elem); }  \
01855            fCanUseCompact = kTRUE;                                        \
01856            XmlReadBasic(vname[index]);                                    \
01857            index++;                                                       \
01858         } else {                                                          \
01859            if (!VerifyItemNode(xmlio::Array,"ReadFastArray")) return;   \
01860            PushStack(StackNode());                                        \
01861            Int_t elemlen = elem->GetArrayLength();                        \
01862            TXMLReadArrayContent((vname+index), elemlen);                  \
01863            PopStack();                                                    \
01864            ShiftStack("readfastarr");                                     \
01865            index+=elemlen;                                                \
01866         }                                                                 \
01867       }                                                                   \
01868    } else {                                                               \
01869       if (!VerifyItemNode(xmlio::Array,"ReadFastArray")) return;        \
01870       PushStack(StackNode());                                             \
01871       TXMLReadArrayContent(vname, n);                                     \
01872       PopStack();                                                         \
01873       ShiftStack("readfastarr");                                          \
01874    }                                                                      \
01875 }
01876 
01877 //______________________________________________________________________________
01878 void TBufferXML::ReadFastArray(Bool_t    *b, Int_t n)
01879 {
01880    // read array of Bool_t from buffer
01881 
01882    TBufferXML_ReadFastArray(b);
01883 }
01884 
01885 //______________________________________________________________________________
01886 void TBufferXML::ReadFastArray(Char_t    *c, Int_t n)
01887 {
01888    // read array of Char_t from buffer
01889    // if nodename==CharStar, read all array as string
01890 
01891    if ((n>0) && VerifyItemNode(xmlio::CharStar)) {
01892       const char* buf;
01893       if ((buf = XmlReadValue(xmlio::CharStar))) {
01894          Int_t size = strlen(buf);
01895          if (size<n) size = n;
01896          memcpy(c, buf, size);
01897       }
01898    } else
01899       TBufferXML_ReadFastArray(c);
01900 }
01901 
01902 //______________________________________________________________________________
01903 void TBufferXML::ReadFastArray(UChar_t   *c, Int_t n)
01904 {
01905    // read array of UChar_t from buffer
01906 
01907    TBufferXML_ReadFastArray(c);
01908 }
01909 
01910 //______________________________________________________________________________
01911 void TBufferXML::ReadFastArray(Short_t   *h, Int_t n)
01912 {
01913    // read array of Short_t from buffer
01914 
01915    TBufferXML_ReadFastArray(h);
01916 }
01917 
01918 //______________________________________________________________________________
01919 void TBufferXML::ReadFastArray(UShort_t  *h, Int_t n)
01920 {
01921    // read array of UShort_t from buffer
01922 
01923    TBufferXML_ReadFastArray(h);
01924 }
01925 
01926 //______________________________________________________________________________
01927 void TBufferXML::ReadFastArray(Int_t     *i, Int_t n)
01928 {
01929    // read array of Int_t from buffer
01930 
01931    TBufferXML_ReadFastArray(i);
01932 }
01933 
01934 //______________________________________________________________________________
01935 void TBufferXML::ReadFastArray(UInt_t    *i, Int_t n)
01936 {
01937    // read array of UInt_t from buffer
01938 
01939    TBufferXML_ReadFastArray(i);
01940 }
01941 
01942 //______________________________________________________________________________
01943 void TBufferXML::ReadFastArray(Long_t    *l, Int_t n)
01944 {
01945    // read array of Long_t from buffer
01946 
01947    TBufferXML_ReadFastArray(l);
01948 }
01949 
01950 //______________________________________________________________________________
01951 void TBufferXML::ReadFastArray(ULong_t   *l, Int_t n)
01952 {
01953    // read array of ULong_t from buffer
01954 
01955    TBufferXML_ReadFastArray(l);
01956 }
01957 
01958 //______________________________________________________________________________
01959 void TBufferXML::ReadFastArray(Long64_t  *l, Int_t n)
01960 {
01961    // read array of Long64_t from buffer
01962 
01963    TBufferXML_ReadFastArray(l);
01964 }
01965 
01966 //______________________________________________________________________________
01967 void TBufferXML::ReadFastArray(ULong64_t *l, Int_t n)
01968 {
01969    // read array of ULong64_t from buffer
01970 
01971    TBufferXML_ReadFastArray(l);
01972 }
01973 
01974 //______________________________________________________________________________
01975 void TBufferXML::ReadFastArray(Float_t   *f, Int_t n)
01976 {
01977    // read array of Float_t from buffer
01978 
01979    TBufferXML_ReadFastArray(f);
01980 }
01981 
01982 //______________________________________________________________________________
01983 void TBufferXML::ReadFastArray(Double_t  *d, Int_t n)
01984 {
01985    // read array of Double_t from buffer
01986 
01987    TBufferXML_ReadFastArray(d);
01988 }
01989 
01990 //______________________________________________________________________________
01991 void TBufferXML::ReadFastArrayFloat16(Float_t  *f, Int_t n, TStreamerElement * /*ele*/)
01992 {
01993    // read array of Float16_t from buffer
01994 
01995    TBufferXML_ReadFastArray(f);
01996 }
01997 
01998 //______________________________________________________________________________
01999 void TBufferXML::ReadFastArrayDouble32(Double_t  *d, Int_t n, TStreamerElement * /*ele*/)
02000 {
02001    // read array of Double32_t from buffer
02002 
02003    TBufferXML_ReadFastArray(d);
02004 }
02005 
02006 //______________________________________________________________________________
02007 void TBufferXML::ReadFastArray(void  *start, const TClass *cl, Int_t n, TMemberStreamer *s, const TClass *onFileClass)
02008 {
02009    // redefined here to avoid warning message from gcc
02010 
02011    TBufferFile::ReadFastArray(start, cl, n, s, onFileClass);
02012 }
02013 
02014 //______________________________________________________________________________
02015 void TBufferXML::ReadFastArray(void **startp, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *s, const TClass *onFileClass)
02016 {
02017    // redefined here to avoid warning message from gcc
02018 
02019    TBufferFile::ReadFastArray(startp, cl, n, isPreAlloc, s, onFileClass);
02020 }
02021 
02022 // macro to write content of noncompressed array
02023 #define TXMLWriteArrayNoncompress(vname, arrsize) \
02024 {                                                 \
02025    for(Int_t indx=0;indx<arrsize;indx++)          \
02026      XmlWriteBasic(vname[indx]);                  \
02027 }
02028 
02029 // macro to write content of compressed array
02030 #define TXMLWriteArrayCompress(vname, arrsize)                     \
02031 {                                                                  \
02032    Int_t indx = 0;                                                 \
02033    while(indx<arrsize) {                                           \
02034       XMLNodePointer_t elemnode = XmlWriteBasic(vname[indx]);      \
02035       Int_t curr = indx; indx++;                                   \
02036       while ((indx<arrsize) && (vname[indx]==vname[curr])) indx++; \
02037       if (indx-curr > 1)                                           \
02038          fXML->NewIntAttr(elemnode, xmlio::cnt, indx-curr);      \
02039    }                                                               \
02040 }
02041 
02042 #define TXMLWriteArrayContent(vname, arrsize)   \
02043 {                                               \
02044    if (fCompressLevel>0) {                      \
02045      TXMLWriteArrayCompress(vname, arrsize)     \
02046    } else {                                     \
02047      TXMLWriteArrayNoncompress(vname, arrsize)  \
02048    }                                            \
02049 }
02050 
02051 // macro to write array, which include size
02052 #define TBufferXML_WriteArray(vname)                          \
02053 {                                                             \
02054    BeforeIOoperation();                                       \
02055    XMLNodePointer_t arrnode = CreateItemNode(xmlio::Array); \
02056    fXML->NewIntAttr(arrnode, xmlio::Size, n);               \
02057    PushStack(arrnode);                                        \
02058    TXMLWriteArrayContent(vname, n);                           \
02059    PopStack();                                                \
02060 }
02061 
02062 //______________________________________________________________________________
02063 void TBufferXML::WriteArray(const Bool_t    *b, Int_t n)
02064 {
02065    // Write array of Bool_t to buffer
02066 
02067    TBufferXML_WriteArray(b);
02068 }
02069 
02070 //______________________________________________________________________________
02071 void TBufferXML::WriteArray(const Char_t    *c, Int_t n)
02072 {
02073    // Write array of Char_t to buffer
02074 
02075    TBufferXML_WriteArray(c);
02076 }
02077 
02078 //______________________________________________________________________________
02079 void TBufferXML::WriteArray(const UChar_t   *c, Int_t n)
02080 {
02081    // Write array of UChar_t to buffer
02082 
02083    TBufferXML_WriteArray(c);
02084 }
02085 
02086 //______________________________________________________________________________
02087 void TBufferXML::WriteArray(const Short_t   *h, Int_t n)
02088 {
02089    // Write array of Short_t to buffer
02090 
02091    TBufferXML_WriteArray(h);
02092 }
02093 
02094 //______________________________________________________________________________
02095 void TBufferXML::WriteArray(const UShort_t  *h, Int_t n)
02096 {
02097    // Write array of UShort_t to buffer
02098 
02099    TBufferXML_WriteArray(h);
02100 }
02101 
02102 //______________________________________________________________________________
02103 void TBufferXML::WriteArray(const Int_t     *i, Int_t n)
02104 {
02105    // Write array of Int_ to buffer
02106 
02107    TBufferXML_WriteArray(i);
02108 }
02109 
02110 //______________________________________________________________________________
02111 void TBufferXML::WriteArray(const UInt_t    *i, Int_t n)
02112 {
02113    // Write array of UInt_t to buffer
02114 
02115    TBufferXML_WriteArray(i);
02116 }
02117 
02118 //______________________________________________________________________________
02119 void TBufferXML::WriteArray(const Long_t    *l, Int_t n)
02120 {
02121    // Write array of Long_t to buffer
02122 
02123    TBufferXML_WriteArray(l);
02124 }
02125 
02126 //______________________________________________________________________________
02127 void TBufferXML::WriteArray(const ULong_t   *l, Int_t n)
02128 {
02129    // Write array of ULong_t to buffer
02130 
02131    TBufferXML_WriteArray(l);
02132 }
02133 
02134 //______________________________________________________________________________
02135 void TBufferXML::WriteArray(const Long64_t  *l, Int_t n)
02136 {
02137    // Write array of Long64_t to buffer
02138 
02139    TBufferXML_WriteArray(l);
02140 }
02141 
02142 //______________________________________________________________________________
02143 void TBufferXML::WriteArray(const ULong64_t *l, Int_t n)
02144 {
02145    // Write array of ULong64_t to buffer
02146 
02147    TBufferXML_WriteArray(l);
02148 }
02149 
02150 //______________________________________________________________________________
02151 void TBufferXML::WriteArray(const Float_t   *f, Int_t n)
02152 {
02153    // Write array of Float_t to buffer
02154 
02155    TBufferXML_WriteArray(f);
02156 }
02157 
02158 //______________________________________________________________________________
02159 void TBufferXML::WriteArray(const Double_t  *d, Int_t n)
02160 {
02161    // Write array of Double_t to buffer
02162 
02163    TBufferXML_WriteArray(d);
02164 }
02165 
02166 //______________________________________________________________________________
02167 void TBufferXML::WriteArrayFloat16(const Float_t  *f, Int_t n, TStreamerElement * /*ele*/)
02168 {
02169    // Write array of Float16_t to buffer
02170 
02171    TBufferXML_WriteArray(f);
02172 }
02173 
02174 //______________________________________________________________________________
02175 void TBufferXML::WriteArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement * /*ele*/)
02176 {
02177    // Write array of Double32_t to buffer
02178 
02179    TBufferXML_WriteArray(d);
02180 }
02181 
02182 // write array without size attribute
02183 // macro also treat situation, when instead of one single array
02184 // chain of several elements should be produced
02185 #define TBufferXML_WriteFastArray(vname)                                  \
02186 {                                                                         \
02187    BeforeIOoperation();                                                   \
02188    if (n<=0) return;                                                      \
02189    TStreamerElement* elem = Stack(0)->fElem;                              \
02190    if ((elem!=0) && (elem->GetType()>TStreamerInfo::kOffsetL) &&          \
02191        (elem->GetType()<TStreamerInfo::kOffsetP) &&                       \
02192        (elem->GetArrayLength()!=n)) fExpectedChain = kTRUE;               \
02193    if (fExpectedChain) {                                                  \
02194       TStreamerInfo* info = Stack(1)->fInfo;                              \
02195       Int_t startnumber = Stack(0)->fElemNumber;                          \
02196       fExpectedChain = kFALSE;                                            \
02197       Int_t number = 0;                                                   \
02198       Int_t index = 0;                                                    \
02199       while (index<n) {                                                   \
02200         elem = info->GetStreamerElementReal(startnumber, number++);       \
02201         if (elem->GetType()<TStreamerInfo::kOffsetL) {                    \
02202           if(index>0) { PopStack(); CreateElemNode(elem); }               \
02203           fCanUseCompact = kTRUE;                                         \
02204           XmlWriteBasic(vname[index]);                                    \
02205           index++;                                                        \
02206         } else {                                                          \
02207           XMLNodePointer_t arrnode = CreateItemNode(xmlio::Array);      \
02208           Int_t elemlen = elem->GetArrayLength();                         \
02209           PushStack(arrnode);                                             \
02210           TXMLWriteArrayContent((vname+index), elemlen);                  \
02211           index+=elemlen;                                                 \
02212           PopStack();                                                     \
02213         }                                                                 \
02214       }                                                                   \
02215    } else {                                                               \
02216       XMLNodePointer_t arrnode = CreateItemNode(xmlio::Array);          \
02217       PushStack(arrnode);                                                 \
02218       TXMLWriteArrayContent(vname, n);                                    \
02219       PopStack();                                                         \
02220    }                                                                      \
02221 }
02222 
02223 //______________________________________________________________________________
02224 void TBufferXML::WriteFastArray(const Bool_t    *b, Int_t n)
02225 {
02226    // Write array of Bool_t to buffer
02227 
02228    TBufferXML_WriteFastArray(b);
02229 }
02230 
02231 //______________________________________________________________________________
02232 void TBufferXML::WriteFastArray(const Char_t    *c, Int_t n)
02233 {
02234    // Write array of Char_t to buffer
02235    // If array does not include any special characters,
02236    // it will be reproduced as CharStar node with string as attribute
02237 
02238    Bool_t usedefault = (n==0) || fExpectedChain;
02239    const Char_t* buf = c;
02240    if (!usedefault)
02241       for (int i=0;i<n;i++) {
02242          if (*buf < 27) { usedefault = kTRUE; break; }
02243          buf++;
02244       }
02245    if (usedefault) {
02246       TBufferXML_WriteFastArray(c);
02247    } else {
02248       Char_t* buf2 = new Char_t[n+1];
02249       memcpy(buf2, c, n);
02250       buf2[n] = 0;
02251       XmlWriteValue(buf2, xmlio::CharStar);
02252       delete[] buf2;
02253    }
02254 }
02255 
02256 //______________________________________________________________________________
02257 void TBufferXML::WriteFastArray(const UChar_t   *c, Int_t n)
02258 {
02259    // Write array of UChar_t to buffer
02260 
02261    TBufferXML_WriteFastArray(c);
02262 }
02263 
02264 //______________________________________________________________________________
02265 void TBufferXML::WriteFastArray(const Short_t   *h, Int_t n)
02266 {
02267    // Write array of Short_t to buffer
02268 
02269    TBufferXML_WriteFastArray(h);
02270 }
02271 
02272 //______________________________________________________________________________
02273 void TBufferXML::WriteFastArray(const UShort_t  *h, Int_t n)
02274 {
02275    // Write array of UShort_t to buffer
02276 
02277    TBufferXML_WriteFastArray(h);
02278 }
02279 
02280 //______________________________________________________________________________
02281 void TBufferXML::WriteFastArray(const Int_t     *i, Int_t n)
02282 {
02283    // Write array of Int_t to buffer
02284 
02285    TBufferXML_WriteFastArray(i);
02286 }
02287 
02288 //______________________________________________________________________________
02289 void TBufferXML::WriteFastArray(const UInt_t    *i, Int_t n)
02290 {
02291    // Write array of UInt_t to buffer
02292 
02293    TBufferXML_WriteFastArray(i);
02294 }
02295 
02296 //______________________________________________________________________________
02297 void TBufferXML::WriteFastArray(const Long_t    *l, Int_t n)
02298 {
02299    // Write array of Long_t to buffer
02300 
02301    TBufferXML_WriteFastArray(l);
02302 }
02303 
02304 //______________________________________________________________________________
02305 void TBufferXML::WriteFastArray(const ULong_t   *l, Int_t n)
02306 {
02307    // Write array of ULong_t to buffer
02308 
02309    TBufferXML_WriteFastArray(l);
02310 }
02311 
02312 //______________________________________________________________________________
02313 void TBufferXML::WriteFastArray(const Long64_t  *l, Int_t n)
02314 {
02315    // Write array of Long64_t to buffer
02316 
02317    TBufferXML_WriteFastArray(l);
02318 }
02319 
02320 //______________________________________________________________________________
02321 void TBufferXML::WriteFastArray(const ULong64_t *l, Int_t n)
02322 {
02323    // Write array of ULong64_t to buffer
02324 
02325    TBufferXML_WriteFastArray(l);
02326 }
02327 
02328 //______________________________________________________________________________
02329 void TBufferXML::WriteFastArray(const Float_t   *f, Int_t n)
02330 {
02331    // Write array of Float_t to buffer
02332 
02333    TBufferXML_WriteFastArray(f);
02334 }
02335 
02336 //______________________________________________________________________________
02337 void TBufferXML::WriteFastArray(const Double_t  *d, Int_t n)
02338 {
02339    // Write array of Double_t to buffer
02340 
02341    TBufferXML_WriteFastArray(d);
02342 }
02343 
02344 //______________________________________________________________________________
02345 void TBufferXML::WriteFastArrayFloat16(const Float_t  *f, Int_t n, TStreamerElement * /*ele*/)
02346 {
02347    // Write array of Float16_t to buffer
02348 
02349    TBufferXML_WriteFastArray(f);
02350 }
02351 
02352 //______________________________________________________________________________
02353 void TBufferXML::WriteFastArrayDouble32(const Double_t  *d, Int_t n, TStreamerElement * /*ele*/)
02354 {
02355    // Write array of Double32_t to buffer
02356 
02357    TBufferXML_WriteFastArray(d);
02358 }
02359 
02360 //______________________________________________________________________________
02361 void  TBufferXML::WriteFastArray(void  *start,  const TClass *cl, Int_t n, TMemberStreamer *s)
02362 {
02363    // Recall TBuffer function to avoid gcc warning message
02364 
02365    TBufferFile::WriteFastArray(start, cl, n, s);
02366 }
02367 
02368 //______________________________________________________________________________
02369 Int_t TBufferXML::WriteFastArray(void **startp, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *s)
02370 {
02371    // Recall TBuffer function to avoid gcc warning message
02372 
02373    return TBufferFile::WriteFastArray(startp, cl, n, isPreAlloc, s);
02374 }
02375 
02376 //______________________________________________________________________________
02377 void TBufferXML::StreamObject(void *obj, const type_info &typeinfo, const TClass* /* onFileClass */ )
02378 {
02379    // steram object to/from buffer
02380 
02381    StreamObject(obj, TClass::GetClass(typeinfo));
02382 }
02383 
02384 //______________________________________________________________________________
02385 void TBufferXML::StreamObject(void *obj, const char *className, const TClass* /* onFileClass */ )
02386 {
02387    // steram object to/from buffer
02388 
02389    StreamObject(obj, TClass::GetClass(className));
02390 }
02391 
02392 void TBufferXML::StreamObject(TObject *obj)
02393 {
02394    // steram object to/from buffer
02395 
02396    StreamObject(obj, obj ? obj->IsA() : TObject::Class());
02397 }
02398 
02399 //______________________________________________________________________________
02400 void TBufferXML::StreamObject(void *obj, const TClass *cl, const TClass* /* onfileClass */ )
02401 {
02402    // steram object to/from buffer
02403 
02404    BeforeIOoperation();
02405    if (gDebug>1)
02406       Info("StreamObject","Class: %s", (cl ? cl->GetName() : "none"));
02407    if (IsReading())
02408       XmlReadObject(obj);
02409    else
02410       XmlWriteObject(obj, cl);
02411 }
02412 
02413 // macro for right shift operator for basic type
02414 #define TBufferXML_operatorin(vname) \
02415 {                                    \
02416   BeforeIOoperation();               \
02417   XmlReadBasic(vname);               \
02418 }
02419 
02420 //______________________________________________________________________________
02421 void TBufferXML::ReadBool(Bool_t    &b)
02422 {
02423    // Reads Bool_t value from buffer
02424 
02425    TBufferXML_operatorin(b);
02426 }
02427 
02428 //______________________________________________________________________________
02429 void TBufferXML::ReadChar(Char_t    &c)
02430 {
02431    // Reads Char_t value from buffer
02432 
02433    TBufferXML_operatorin(c);
02434 }
02435 
02436 //______________________________________________________________________________
02437 void TBufferXML::ReadUChar(UChar_t   &c)
02438 {
02439    // Reads UChar_t value from buffer
02440 
02441    TBufferXML_operatorin(c);
02442 }
02443 
02444 //______________________________________________________________________________
02445 void TBufferXML::ReadShort(Short_t   &h)
02446 {
02447    // Reads Short_t value from buffer
02448 
02449    TBufferXML_operatorin(h);
02450 }
02451 
02452 //______________________________________________________________________________
02453 void TBufferXML::ReadUShort(UShort_t  &h)
02454 {
02455    // Reads UShort_t value from buffer
02456 
02457    TBufferXML_operatorin(h);
02458 }
02459 
02460 //______________________________________________________________________________
02461 void TBufferXML::ReadInt(Int_t     &i)
02462 {
02463    // Reads Int_t value from buffer
02464 
02465    TBufferXML_operatorin(i);
02466 }
02467 
02468 //______________________________________________________________________________
02469 void TBufferXML::ReadUInt(UInt_t    &i)
02470 {
02471    // Reads UInt_t value from buffer
02472 
02473    TBufferXML_operatorin(i);
02474 }
02475 
02476 //______________________________________________________________________________
02477 void TBufferXML::ReadLong(Long_t    &l)
02478 {
02479    // Reads Long_t value from buffer
02480 
02481    TBufferXML_operatorin(l);
02482 }
02483 
02484 //______________________________________________________________________________
02485 void TBufferXML::ReadULong(ULong_t   &l)
02486 {
02487    // Reads ULong_t value from buffer
02488 
02489    TBufferXML_operatorin(l);
02490 }
02491 
02492 //______________________________________________________________________________
02493 void TBufferXML::ReadLong64(Long64_t  &l)
02494 {
02495    // Reads Long64_t value from buffer
02496 
02497    TBufferXML_operatorin(l);
02498 }
02499 
02500 //______________________________________________________________________________
02501 void TBufferXML::ReadULong64(ULong64_t &l)
02502 {
02503    // Reads ULong64_t value from buffer
02504 
02505    TBufferXML_operatorin(l);
02506 }
02507 
02508 //______________________________________________________________________________
02509 void TBufferXML::ReadFloat(Float_t   &f)
02510 {
02511    // Reads Float_t value from buffer
02512 
02513    TBufferXML_operatorin(f);
02514 }
02515 
02516 //______________________________________________________________________________
02517 void TBufferXML::ReadDouble(Double_t  &d)
02518 {
02519    // Reads Double_t value from buffer
02520 
02521    TBufferXML_operatorin(d);
02522 }
02523 
02524 //______________________________________________________________________________
02525 void TBufferXML::ReadCharP(Char_t    *c)
02526 {
02527    // Reads array of characters from buffer
02528 
02529    BeforeIOoperation();
02530    const char* buf;
02531    if ((buf = XmlReadValue(xmlio::CharStar)))
02532       strcpy(c, buf);
02533 }
02534 
02535 //______________________________________________________________________________
02536 void TBufferXML::ReadTString(TString & /*s*/)
02537 {
02538    // Reads a TString
02539 
02540    //BeforeIOoperation();
02541    //const char* buf = XmlReadValue(xmlio::CharStar);
02542    //strcpy(c, buf);
02543    //TO BE IMPLEMENTED
02544 }
02545 
02546 // macro for left shift operator for basic types
02547 #define TBufferXML_operatorout(vname) \
02548 {                                     \
02549   BeforeIOoperation();                \
02550   XmlWriteBasic(vname);               \
02551 }
02552 
02553 //______________________________________________________________________________
02554 void TBufferXML::WriteBool(Bool_t    b)
02555 {
02556    // Writes Bool_t value to buffer
02557 
02558    TBufferXML_operatorout(b);
02559 }
02560 
02561 //______________________________________________________________________________
02562 void TBufferXML::WriteChar(Char_t    c)
02563 {
02564    // Writes Char_t value to buffer
02565 
02566    TBufferXML_operatorout(c);
02567 }
02568 
02569 //______________________________________________________________________________
02570 void TBufferXML::WriteUChar(UChar_t   c)
02571 {
02572    // Writes UChar_t value to buffer
02573 
02574    TBufferXML_operatorout(c);
02575 }
02576 
02577 //______________________________________________________________________________
02578 void TBufferXML::WriteShort(Short_t   h)
02579 {
02580    // Writes Short_t value to buffer
02581 
02582    TBufferXML_operatorout(h);
02583 }
02584 
02585 //______________________________________________________________________________
02586 void TBufferXML::WriteUShort(UShort_t  h)
02587 {
02588    // Writes UShort_t value to buffer
02589 
02590    TBufferXML_operatorout(h);
02591 }
02592 
02593 //______________________________________________________________________________
02594 void TBufferXML::WriteInt(Int_t     i)
02595 {
02596    // Writes Int_t value to buffer
02597 
02598    TBufferXML_operatorout(i);
02599 }
02600 
02601 //______________________________________________________________________________
02602 void TBufferXML::WriteUInt(UInt_t    i)
02603 {
02604    // Writes UInt_t value to buffer
02605 
02606    TBufferXML_operatorout(i);
02607 }
02608 
02609 //______________________________________________________________________________
02610 void TBufferXML::WriteLong(Long_t    l)
02611 {
02612    // Writes Long_t value to buffer
02613 
02614    TBufferXML_operatorout(l);
02615 }
02616 
02617 //______________________________________________________________________________
02618 void TBufferXML::WriteULong(ULong_t   l)
02619 {
02620    // Writes ULong_t value to buffer
02621 
02622    TBufferXML_operatorout(l);
02623 }
02624 
02625 //______________________________________________________________________________
02626 void TBufferXML::WriteLong64(Long64_t  l)
02627 {
02628    // Writes Long64_t value to buffer
02629 
02630    TBufferXML_operatorout(l);
02631 }
02632 
02633 //______________________________________________________________________________
02634 void TBufferXML::WriteULong64(ULong64_t l)
02635 {
02636    // Writes ULong64_t value to buffer
02637 
02638    TBufferXML_operatorout(l);
02639 }
02640 
02641 //______________________________________________________________________________
02642 void TBufferXML::WriteFloat(Float_t   f)
02643 {
02644    // Writes Float_t value to buffer
02645 
02646    TBufferXML_operatorout(f);
02647 }
02648 
02649 //______________________________________________________________________________
02650 void TBufferXML::WriteDouble(Double_t  d)
02651 {
02652    // Writes Double_t value to buffer
02653 
02654    TBufferXML_operatorout(d);
02655 }
02656 
02657 //______________________________________________________________________________
02658 void TBufferXML::WriteCharP(const Char_t *c)
02659 {
02660    // Writes array of characters to buffer
02661 
02662    BeforeIOoperation();
02663    XmlWriteValue(c, xmlio::CharStar);
02664 }
02665 
02666 //______________________________________________________________________________
02667 void TBufferXML::WriteTString(const TString & /*s*/)
02668 {
02669    // Writes a TString
02670 
02671    //BeforeIOoperation();
02672    //XmlWriteValue(c, xmlio::CharStar);
02673    //TO BE IMPLEMENTED
02674 }
02675 
02676 //______________________________________________________________________________
02677 XMLNodePointer_t TBufferXML::XmlWriteBasic(Char_t value)
02678 {
02679    // converts Char_t to string and add xml node to buffer
02680 
02681    char buf[50];
02682    snprintf(buf, sizeof(buf), "%d",value);
02683    return XmlWriteValue(buf, xmlio::Char);
02684 }
02685 
02686 //______________________________________________________________________________
02687 XMLNodePointer_t  TBufferXML::XmlWriteBasic(Short_t value)
02688 {
02689    // converts Short_t to string and add xml node to buffer
02690 
02691    char buf[50];
02692    snprintf(buf, sizeof(buf), "%hd", value);
02693    return XmlWriteValue(buf, xmlio::Short);
02694 }
02695 
02696 //______________________________________________________________________________
02697 XMLNodePointer_t TBufferXML::XmlWriteBasic(Int_t value)
02698 {
02699    // converts Int_t to string and add xml node to buffer
02700 
02701    char buf[50];
02702    snprintf(buf, sizeof(buf), "%d", value);
02703    return XmlWriteValue(buf, xmlio::Int);
02704 }
02705 
02706 //______________________________________________________________________________
02707 XMLNodePointer_t TBufferXML::XmlWriteBasic(Long_t value)
02708 {
02709    // converts Long_t to string and add xml node to buffer
02710 
02711    char buf[50];
02712    snprintf(buf, sizeof(buf), "%ld", value);
02713    return XmlWriteValue(buf, xmlio::Long);
02714 }
02715 
02716 //______________________________________________________________________________
02717 XMLNodePointer_t TBufferXML::XmlWriteBasic(Long64_t value)
02718 {
02719    // converts Long64_t to string and add xml node to buffer
02720 
02721    char buf[50];
02722    snprintf(buf, sizeof(buf), FLong64, value);
02723    return XmlWriteValue(buf, xmlio::Long64);
02724 }
02725 
02726 //______________________________________________________________________________
02727 XMLNodePointer_t  TBufferXML::XmlWriteBasic(Float_t value)
02728 {
02729    // converts Float_t to string and add xml node to buffer
02730 
02731    char buf[200];
02732    snprintf(buf, sizeof(buf), fgFloatFmt, value);
02733    return XmlWriteValue(buf, xmlio::Float);
02734 }
02735 
02736 //______________________________________________________________________________
02737 XMLNodePointer_t TBufferXML::XmlWriteBasic(Double_t value)
02738 {
02739    // converts Double_t to string and add xml node to buffer
02740 
02741    char buf[1000];
02742    snprintf(buf, sizeof(buf), fgFloatFmt, value);
02743    return XmlWriteValue(buf, xmlio::Double);
02744 }
02745 
02746 //______________________________________________________________________________
02747 XMLNodePointer_t TBufferXML::XmlWriteBasic(Bool_t value)
02748 {
02749    // converts Bool_t to string and add xml node to buffer
02750 
02751    return XmlWriteValue(value ? xmlio::True : xmlio::False, xmlio::Bool);
02752 }
02753 
02754 //______________________________________________________________________________
02755 XMLNodePointer_t TBufferXML::XmlWriteBasic(UChar_t value)
02756 {
02757    // converts UChar_t to string and add xml node to buffer
02758 
02759    char buf[50];
02760    snprintf(buf, sizeof(buf), "%u", value);
02761    return XmlWriteValue(buf, xmlio::UChar);
02762 }
02763 
02764 //______________________________________________________________________________
02765 XMLNodePointer_t TBufferXML::XmlWriteBasic(UShort_t value)
02766 {
02767    // converts UShort_t to string and add xml node to buffer
02768 
02769    char buf[50];
02770    snprintf(buf, sizeof(buf), "%hu", value);
02771    return XmlWriteValue(buf, xmlio::UShort);
02772 }
02773 
02774 //______________________________________________________________________________
02775 XMLNodePointer_t TBufferXML::XmlWriteBasic(UInt_t value)
02776 {
02777    // converts UInt_t to string and add xml node to buffer
02778 
02779    char buf[50];
02780    snprintf(buf, sizeof(buf), "%u", value);
02781    return XmlWriteValue(buf, xmlio::UInt);
02782 }
02783 
02784 //______________________________________________________________________________
02785 XMLNodePointer_t TBufferXML::XmlWriteBasic(ULong_t value)
02786 {
02787    // converts ULong_t to string and add xml node to buffer
02788 
02789    char buf[50];
02790    snprintf(buf, sizeof(buf), "%lu", value);
02791    return XmlWriteValue(buf, xmlio::ULong);
02792 }
02793 
02794 //______________________________________________________________________________
02795 XMLNodePointer_t TBufferXML::XmlWriteBasic(ULong64_t value)
02796 {
02797    // converts ULong64_t to string and add xml node to buffer
02798 
02799    char buf[50];
02800    snprintf(buf, sizeof(buf), FULong64, value);
02801    return XmlWriteValue(buf, xmlio::ULong64);
02802 }
02803 
02804 //______________________________________________________________________________
02805 XMLNodePointer_t TBufferXML::XmlWriteValue(const char* value, const char* name)
02806 {
02807    // create xml node with specified name and adds it to stack node
02808 
02809    XMLNodePointer_t node = 0;
02810 
02811    if (fCanUseCompact)
02812       node = StackNode();
02813    else
02814       node = CreateItemNode(name);
02815 
02816    fXML->NewAttr(node, 0, xmlio::v, value);
02817 
02818    fCanUseCompact = kFALSE;
02819 
02820    return node;
02821 }
02822 
02823 //______________________________________________________________________________
02824 void TBufferXML::XmlReadBasic(Char_t& value)
02825 {
02826    // reads string from current xml node and convert it to Char_t value
02827 
02828    const char* res = XmlReadValue(xmlio::Char);
02829    if (res) {
02830       int n;
02831       sscanf(res,"%d", &n);
02832       value = n;
02833    } else
02834       value = 0;
02835 }
02836 
02837 //______________________________________________________________________________
02838 void TBufferXML::XmlReadBasic(Short_t& value)
02839 {
02840    // reads string from current xml node and convert it to Short_t value
02841 
02842    const char* res = XmlReadValue(xmlio::Short);
02843    if (res)
02844       sscanf(res,"%hd", &value);
02845    else
02846       value = 0;
02847 }
02848 
02849 //______________________________________________________________________________
02850 void TBufferXML::XmlReadBasic(Int_t& value)
02851 {
02852    // reads string from current xml node and convert it to Int_t value
02853 
02854    const char* res = XmlReadValue(xmlio::Int);
02855    if (res)
02856       sscanf(res,"%d", &value);
02857    else
02858       value = 0;
02859 }
02860 
02861 //______________________________________________________________________________
02862 void TBufferXML::XmlReadBasic(Long_t& value)
02863 {
02864    // reads string from current xml node and convert it to Long_t value
02865 
02866    const char* res = XmlReadValue(xmlio::Long);
02867    if (res)
02868       sscanf(res,"%ld", &value);
02869    else
02870       value = 0;
02871 }
02872 
02873 //______________________________________________________________________________
02874 void TBufferXML::XmlReadBasic(Long64_t& value)
02875 {
02876    // reads string from current xml node and convert it to Long64_t value
02877 
02878    const char* res = XmlReadValue(xmlio::Long64);
02879    if (res)
02880       sscanf(res, FLong64, &value);
02881    else
02882       value = 0;
02883 }
02884 
02885 //______________________________________________________________________________
02886 void TBufferXML::XmlReadBasic(Float_t& value)
02887 {
02888    // reads string from current xml node and convert it to Float_t value
02889 
02890    const char* res = XmlReadValue(xmlio::Float);
02891    if (res)
02892       sscanf(res, "%f", &value);
02893    else
02894       value = 0.;
02895 }
02896 
02897 //______________________________________________________________________________
02898 void TBufferXML::XmlReadBasic(Double_t& value)
02899 {
02900    // reads string from current xml node and convert it to Double_t value
02901 
02902    const char* res = XmlReadValue(xmlio::Double);
02903    if (res)
02904       sscanf(res, "%lf", &value);
02905    else
02906       value = 0.;
02907 }
02908 
02909 //______________________________________________________________________________
02910 void TBufferXML::XmlReadBasic(Bool_t& value)
02911 {
02912    // reads string from current xml node and convert it to Bool_t value
02913 
02914    const char* res = XmlReadValue(xmlio::Bool);
02915    if (res)
02916       value = (strcmp(res, xmlio::True)==0);
02917    else
02918       value = kFALSE;
02919 }
02920 
02921 //______________________________________________________________________________
02922 void TBufferXML::XmlReadBasic(UChar_t& value)
02923 {
02924    // reads string from current xml node and convert it to UChar_t value
02925 
02926    const char* res = XmlReadValue(xmlio::UChar);
02927    if (res) {
02928       unsigned int n;
02929       sscanf(res,"%ud", &n);
02930       value = n;
02931    } else
02932       value = 0;
02933 }
02934 
02935 //______________________________________________________________________________
02936 void TBufferXML::XmlReadBasic(UShort_t& value)
02937 {
02938    // reads string from current xml node and convert it to UShort_t value
02939 
02940    const char* res = XmlReadValue(xmlio::UShort);
02941    if (res)
02942       sscanf(res,"%hud", &value);
02943    else
02944       value = 0;
02945 }
02946 
02947 //______________________________________________________________________________
02948 void TBufferXML::XmlReadBasic(UInt_t& value)
02949 {
02950    // reads string from current xml node and convert it to UInt_t value
02951 
02952    const char* res = XmlReadValue(xmlio::UInt);
02953    if (res)
02954       sscanf(res,"%u", &value);
02955    else
02956       value = 0;
02957 }
02958 
02959 //______________________________________________________________________________
02960 void TBufferXML::XmlReadBasic(ULong_t& value)
02961 {
02962    // reads string from current xml node and convert it to ULong_t value
02963 
02964    const char* res = XmlReadValue(xmlio::ULong);
02965    if (res)
02966       sscanf(res,"%lu", &value);
02967    else
02968       value = 0;
02969 }
02970 
02971 //______________________________________________________________________________
02972 void TBufferXML::XmlReadBasic(ULong64_t& value)
02973 {
02974    // reads string from current xml node and convert it to ULong64_t value
02975 
02976    const char* res = XmlReadValue(xmlio::ULong64);
02977    if (res)
02978       sscanf(res, FULong64, &value);
02979    else
02980       value = 0;
02981 }
02982 
02983 //______________________________________________________________________________
02984 const char* TBufferXML::XmlReadValue(const char* name)
02985 {
02986    // read string value from current stack node
02987 
02988    if (fErrorFlag>0) return 0;
02989 
02990    Bool_t trysimple = fCanUseCompact;
02991    fCanUseCompact = kFALSE;
02992 
02993    if (trysimple) {
02994       if (fXML->HasAttr(Stack(1)->fNode,xmlio::v))
02995          fValueBuf = fXML->GetAttr(Stack(1)->fNode, xmlio::v);
02996       else
02997          trysimple = kFALSE;
02998    }
02999 
03000    if (!trysimple) {
03001       if (!VerifyItemNode(name, "XmlReadValue")) return 0;
03002       fValueBuf = fXML->GetAttr(StackNode(), xmlio::v);
03003    }
03004 
03005    if (gDebug>4)
03006       Info("XmlReadValue","     Name = %s value = %s", name, fValueBuf.Data());
03007 
03008    if (!trysimple)
03009       ShiftStack("readvalue");
03010 
03011    return fValueBuf.Data();
03012 }
03013 
03014 void TBufferXML::SetFloatFormat(const char* fmt)
03015 {
03016    // set printf format for float/double members, default "%e"
03017 
03018    if (fmt==0) fmt = "%e";
03019    fgFloatFmt = fmt;
03020 }
03021 
03022 const char* TBufferXML::GetFloatFormat()
03023 {
03024    // return current printf format for float/double members, default "%e"
03025 
03026    return fgFloatFmt;
03027 }
03028 
03029 //______________________________________________________________________________
03030 Int_t TBufferXML::ReadSequence(const TStreamerInfoActions::TActionSequence &sequence, void *obj) 
03031 {
03032    // Read one collection of objects from the buffer using the StreamerInfoLoopAction.
03033    // The collection needs to be a split TClonesArray or a split vector of pointers.
03034    
03035    TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03036    IncrementLevel(info);
03037    
03038    if (gDebug) {
03039       //loop on all active members
03040       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03041       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03042           iter != end;
03043           ++iter) {      
03044          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03045          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03046          (*iter).PrintDebug(*this,obj);
03047          (*iter)(*this,obj);
03048       }
03049       
03050    } else {
03051       //loop on all active members
03052       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03053       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03054           iter != end;
03055           ++iter) {      
03056          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03057          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03058          (*iter)(*this,obj);
03059       }
03060    }
03061    
03062    DecrementLevel(info);
03063    return 0;
03064 }
03065 
03066 //______________________________________________________________________________
03067 Int_t TBufferXML::ReadSequenceVecPtr(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection) 
03068 {
03069    // Read one collection of objects from the buffer using the StreamerInfoLoopAction.
03070    // The collection needs to be a split TClonesArray or a split vector of pointers.
03071    
03072    TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03073    IncrementLevel(info);
03074    
03075    if (gDebug) {
03076       //loop on all active members
03077       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03078       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03079           iter != end;
03080           ++iter) {      
03081          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03082          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03083          (*iter).PrintDebug(*this,*(char**)start_collection);  // Warning: This limits us to TClonesArray and vector of pointers.
03084          (*iter)(*this,start_collection,end_collection);
03085       }
03086       
03087    } else {
03088       //loop on all active members
03089       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03090       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03091           iter != end;
03092           ++iter) {      
03093          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03094          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03095          (*iter)(*this,start_collection,end_collection);
03096       }
03097    }
03098    
03099    DecrementLevel(info);
03100    return 0;
03101 }
03102 
03103 //______________________________________________________________________________
03104 Int_t TBufferXML::ReadSequence(const TStreamerInfoActions::TActionSequence &sequence, void *start_collection, void *end_collection) 
03105 {
03106    // Read one collection of objects from the buffer using the StreamerInfoLoopAction.
03107    
03108    TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03109    IncrementLevel(info);
03110    
03111    TStreamerInfoActions::TLoopConfiguration *loopconfig = sequence.fLoopConfig;
03112    if (gDebug) {
03113       
03114       // Get the address of the first item for the PrintDebug.
03115       // (Performance is not essential here since we are going to print to
03116       // the screen anyway).
03117       void *arr0 = loopconfig->GetFirstAddress(start_collection,end_collection);
03118       // loop on all active members
03119       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03120       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03121           iter != end;
03122           ++iter) {      
03123          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03124          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03125          (*iter).PrintDebug(*this,arr0);
03126          (*iter)(*this,start_collection,end_collection,loopconfig);
03127       }
03128       
03129    } else {
03130       //loop on all active members
03131       TStreamerInfoActions::ActionContainer_t::const_iterator end = sequence.fActions.end();
03132       for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = sequence.fActions.begin();
03133           iter != end;
03134           ++iter) {      
03135          // Idea: Try to remove this function call as it is really needed only for XML streaming.
03136          SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03137          (*iter)(*this,start_collection,end_collection,loopconfig);
03138       }
03139    }
03140    
03141    DecrementLevel(info);
03142    return 0;
03143 }

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