00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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
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
00095
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
00119
00120
00121
00122
00123
00124
00125
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
00141
00142 if (fObjMap) delete fObjMap;
00143 if (fIdArray) delete fIdArray;
00144 fStack.Delete();
00145 }
00146
00147
00148 TXMLFile* TBufferXML::XmlFile()
00149 {
00150
00151
00152
00153 return dynamic_cast<TXMLFile*>(GetParent());
00154 }
00155
00156
00157 TString TBufferXML::ConvertToXML(TObject* obj, Bool_t GenericLayout, Bool_t UseNamespaces)
00158 {
00159
00160
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
00169
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
00194
00195
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
00216
00217
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
00240
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
00255
00256
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
00278
00279
00280
00281
00282 TBufferFile::WriteObject(obj);
00283 }
00284
00285
00286
00287
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
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
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
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
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
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
00385
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
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
00499
00500
00501
00502 if (node==0) return kFALSE;
00503
00504 TString refvalue;
00505
00506 if (ptr==0)
00507 refvalue = xmlio::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
00539
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
00555
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
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
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
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
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
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
00656
00657 return VerifyAttr(StackNode(), name, value, errinfo);
00658 }
00659
00660
00661 XMLNodePointer_t TBufferXML::CreateItemNode(const char* name)
00662 {
00663
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
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
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
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
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());
00733 curr->fElem = (TStreamerElement*)elem;
00734 return kTRUE;
00735 }
00736
00737
00738 XMLNodePointer_t TBufferXML::XmlWriteObject(const void* obj, const TClass* cl)
00739 {
00740
00741
00742
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
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
00827
00828
00829
00830
00831 WorkWithClass((TStreamerInfo*)info);
00832 }
00833
00834
00835 void TBufferXML::WorkWithClass(TStreamerInfo* sinfo, const TClass* cl)
00836 {
00837
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
00898
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();
00913 }
00914
00915 if (stack->fCompressedClassNode) {
00916 stack->fInfo = 0;
00917 stack->fIsStreamerInfo = kFALSE;
00918 stack->fCompressedClassNode = kFALSE;
00919 } else {
00920 PopStack();
00921 if (IsReading()) ShiftStack("declevel");
00922 }
00923 }
00924
00925
00926 void TBufferXML::SetStreamerElementNumber(Int_t number)
00927 {
00928
00929
00930
00931
00932 WorkWithElement(0, number);
00933 }
00934
00935
00936 void TBufferXML::WorkWithElement(TStreamerElement* elem, Int_t number)
00937 {
00938
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()) {
00952 PerformPostProcessing();
00953 PopStack();
00954 if (IsReading()) ShiftStack("startelem");
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
01025 WorkWithClass(0, cl);
01026 }
01027
01028
01029 void TBufferXML::ClassEnd(const TClass*)
01030 {
01031
01032 DecrementLevel(0);
01033 }
01034
01035
01036 void TBufferXML::ClassMember(const char* name, const char* typeName, Int_t arrsize1, Int_t arrsize2)
01037 {
01038
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
01145 WorkWithElement(elem, -1);
01146 }
01147
01148
01149 void TBufferXML::PerformPostProcessing()
01150 {
01151
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;
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
01252
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
01317
01318
01319 CheckVersionBuf();
01320 }
01321
01322
01323 TClass* TBufferXML::ReadClass(const TClass*, UInt_t*)
01324 {
01325
01326
01327 return 0;
01328 }
01329
01330
01331 void TBufferXML::WriteClass(const TClass*)
01332 {
01333
01334
01335 }
01336
01337
01338 Int_t TBufferXML::CheckByteCount(UInt_t , UInt_t , const TClass* )
01339 {
01340
01341
01342 return 0;
01343 }
01344
01345
01346 Int_t TBufferXML::CheckByteCount(UInt_t, UInt_t, const char*)
01347 {
01348
01349
01350 return 0;
01351 }
01352
01353
01354 void TBufferXML::SetByteCount(UInt_t, Bool_t)
01355 {
01356
01357
01358 }
01359
01360
01361 void TBufferXML::SkipVersion(const TClass *cl)
01362 {
01363
01364 ReadVersion(0,0,cl);
01365 }
01366
01367
01368 Version_t TBufferXML::ReadVersion(UInt_t *start, UInt_t *bcnt, const TClass * )
01369 {
01370
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
01401
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 )
01413 {
01414
01415
01416
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
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
01448
01449
01450 ShiftStack("skipobjectany"); \
01451 }
01452
01453
01454 void TBufferXML::WriteObjectClass(const void *actualObjStart, const TClass *actualClass)
01455 {
01456
01457
01458 BeforeIOoperation();
01459 if (gDebug>2)
01460 Info("WriteObject","Class %s", (actualClass ? actualClass->GetName() : " null"));
01461 XmlWriteObject(actualObjStart, actualClass);
01462 }
01463
01464
01465 #define TXMLReadArrayNoncompress(vname) \
01466 { \
01467 for(Int_t indx=0;indx<n;indx++) \
01468 XmlReadBasic(vname[indx]); \
01469 }
01470
01471
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
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 * )
01505 {
01506
01507 BeforeIOoperation();
01508 XmlReadBasic(*f);
01509 }
01510
01511
01512 void TBufferXML::ReadDouble32 (Double_t *d, TStreamerElement * )
01513 {
01514
01515 BeforeIOoperation();
01516 XmlReadBasic(*d);
01517 }
01518
01519
01520 void TBufferXML::ReadWithFactor(Float_t *ptr, Double_t , Double_t )
01521 {
01522
01523
01524
01525
01526 BeforeIOoperation();
01527 XmlReadBasic(*ptr);
01528 }
01529
01530
01531 void TBufferXML::ReadWithNbits(Float_t *ptr, Int_t )
01532 {
01533
01534
01535
01536
01537 BeforeIOoperation();
01538 XmlReadBasic(*ptr);
01539 }
01540
01541
01542 void TBufferXML::ReadWithFactor(Double_t *ptr, Double_t , Double_t )
01543 {
01544
01545
01546
01547
01548 BeforeIOoperation();
01549 XmlReadBasic(*ptr);
01550 }
01551
01552
01553 void TBufferXML::ReadWithNbits(Double_t *ptr, Int_t )
01554 {
01555
01556
01557
01558
01559 BeforeIOoperation();
01560 XmlReadBasic(*ptr);
01561 }
01562
01563
01564 void TBufferXML::WriteFloat16 (Float_t *f, TStreamerElement * )
01565 {
01566
01567 BeforeIOoperation();
01568 XmlWriteBasic(*f);
01569 }
01570
01571
01572 void TBufferXML::WriteDouble32 (Double_t *d, TStreamerElement * )
01573 {
01574
01575 BeforeIOoperation();
01576 XmlWriteBasic(*d);
01577 }
01578
01579
01580 Int_t TBufferXML::ReadArray(Bool_t *&b)
01581 {
01582
01583
01584 TBufferXML_ReadArray(Bool_t,b);
01585 }
01586
01587
01588 Int_t TBufferXML::ReadArray(Char_t *&c)
01589 {
01590
01591
01592 TBufferXML_ReadArray(Char_t,c);
01593 }
01594
01595
01596 Int_t TBufferXML::ReadArray(UChar_t *&c)
01597 {
01598
01599
01600 TBufferXML_ReadArray(UChar_t,c);
01601 }
01602
01603
01604 Int_t TBufferXML::ReadArray(Short_t *&h)
01605 {
01606
01607
01608 TBufferXML_ReadArray(Short_t,h);
01609 }
01610
01611
01612 Int_t TBufferXML::ReadArray(UShort_t *&h)
01613 {
01614
01615
01616 TBufferXML_ReadArray(UShort_t,h);
01617 }
01618
01619
01620 Int_t TBufferXML::ReadArray(Int_t *&i)
01621 {
01622
01623
01624 TBufferXML_ReadArray(Int_t,i);
01625 }
01626
01627
01628 Int_t TBufferXML::ReadArray(UInt_t *&i)
01629 {
01630
01631
01632 TBufferXML_ReadArray(UInt_t,i);
01633 }
01634
01635
01636 Int_t TBufferXML::ReadArray(Long_t *&l)
01637 {
01638
01639
01640 TBufferXML_ReadArray(Long_t,l);
01641 }
01642
01643
01644 Int_t TBufferXML::ReadArray(ULong_t *&l)
01645 {
01646
01647
01648 TBufferXML_ReadArray(ULong_t,l);
01649 }
01650
01651
01652 Int_t TBufferXML::ReadArray(Long64_t *&l)
01653 {
01654
01655
01656 TBufferXML_ReadArray(Long64_t,l);
01657 }
01658
01659
01660 Int_t TBufferXML::ReadArray(ULong64_t *&l)
01661 {
01662
01663
01664 TBufferXML_ReadArray(ULong64_t,l);
01665 }
01666
01667
01668 Int_t TBufferXML::ReadArray(Float_t *&f)
01669 {
01670
01671
01672 TBufferXML_ReadArray(Float_t,f);
01673 }
01674
01675
01676 Int_t TBufferXML::ReadArray(Double_t *&d)
01677 {
01678
01679
01680 TBufferXML_ReadArray(Double_t,d);
01681 }
01682
01683
01684 Int_t TBufferXML::ReadArrayFloat16(Float_t *&f, TStreamerElement * )
01685 {
01686
01687
01688 TBufferXML_ReadArray(Float_t,f);
01689 }
01690
01691
01692 Int_t TBufferXML::ReadArrayDouble32(Double_t *&d, TStreamerElement * )
01693 {
01694
01695
01696 TBufferXML_ReadArray(Double_t,d);
01697 }
01698
01699
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
01718
01719 TBufferXML_ReadStaticArray(b);
01720 }
01721
01722
01723 Int_t TBufferXML::ReadStaticArray(Char_t *c)
01724 {
01725
01726
01727 TBufferXML_ReadStaticArray(c);
01728 }
01729
01730
01731 Int_t TBufferXML::ReadStaticArray(UChar_t *c)
01732 {
01733
01734
01735 TBufferXML_ReadStaticArray(c);
01736 }
01737
01738
01739 Int_t TBufferXML::ReadStaticArray(Short_t *h)
01740 {
01741
01742
01743 TBufferXML_ReadStaticArray(h);
01744 }
01745
01746
01747 Int_t TBufferXML::ReadStaticArray(UShort_t *h)
01748 {
01749
01750
01751 TBufferXML_ReadStaticArray(h);
01752 }
01753
01754
01755 Int_t TBufferXML::ReadStaticArray(Int_t *i)
01756 {
01757
01758
01759 TBufferXML_ReadStaticArray(i);
01760 }
01761
01762
01763 Int_t TBufferXML::ReadStaticArray(UInt_t *i)
01764 {
01765
01766
01767 TBufferXML_ReadStaticArray(i);
01768 }
01769
01770
01771 Int_t TBufferXML::ReadStaticArray(Long_t *l)
01772 {
01773
01774
01775 TBufferXML_ReadStaticArray(l);
01776 }
01777
01778
01779 Int_t TBufferXML::ReadStaticArray(ULong_t *l)
01780 {
01781
01782
01783 TBufferXML_ReadStaticArray(l);
01784 }
01785
01786
01787 Int_t TBufferXML::ReadStaticArray(Long64_t *l)
01788 {
01789
01790
01791 TBufferXML_ReadStaticArray(l);
01792 }
01793
01794
01795 Int_t TBufferXML::ReadStaticArray(ULong64_t *l)
01796 {
01797
01798
01799 TBufferXML_ReadStaticArray(l);
01800 }
01801
01802
01803 Int_t TBufferXML::ReadStaticArray(Float_t *f)
01804 {
01805
01806
01807 TBufferXML_ReadStaticArray(f);
01808 }
01809
01810
01811 Int_t TBufferXML::ReadStaticArray(Double_t *d)
01812 {
01813
01814
01815 TBufferXML_ReadStaticArray(d);
01816 }
01817
01818
01819 Int_t TBufferXML::ReadStaticArrayFloat16(Float_t *f, TStreamerElement * )
01820 {
01821
01822
01823 TBufferXML_ReadStaticArray(f);
01824 }
01825
01826
01827 Int_t TBufferXML::ReadStaticArrayDouble32(Double_t *d, TStreamerElement * )
01828 {
01829
01830
01831 TBufferXML_ReadStaticArray(d);
01832 }
01833
01834
01835
01836
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
01881
01882 TBufferXML_ReadFastArray(b);
01883 }
01884
01885
01886 void TBufferXML::ReadFastArray(Char_t *c, Int_t n)
01887 {
01888
01889
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
01906
01907 TBufferXML_ReadFastArray(c);
01908 }
01909
01910
01911 void TBufferXML::ReadFastArray(Short_t *h, Int_t n)
01912 {
01913
01914
01915 TBufferXML_ReadFastArray(h);
01916 }
01917
01918
01919 void TBufferXML::ReadFastArray(UShort_t *h, Int_t n)
01920 {
01921
01922
01923 TBufferXML_ReadFastArray(h);
01924 }
01925
01926
01927 void TBufferXML::ReadFastArray(Int_t *i, Int_t n)
01928 {
01929
01930
01931 TBufferXML_ReadFastArray(i);
01932 }
01933
01934
01935 void TBufferXML::ReadFastArray(UInt_t *i, Int_t n)
01936 {
01937
01938
01939 TBufferXML_ReadFastArray(i);
01940 }
01941
01942
01943 void TBufferXML::ReadFastArray(Long_t *l, Int_t n)
01944 {
01945
01946
01947 TBufferXML_ReadFastArray(l);
01948 }
01949
01950
01951 void TBufferXML::ReadFastArray(ULong_t *l, Int_t n)
01952 {
01953
01954
01955 TBufferXML_ReadFastArray(l);
01956 }
01957
01958
01959 void TBufferXML::ReadFastArray(Long64_t *l, Int_t n)
01960 {
01961
01962
01963 TBufferXML_ReadFastArray(l);
01964 }
01965
01966
01967 void TBufferXML::ReadFastArray(ULong64_t *l, Int_t n)
01968 {
01969
01970
01971 TBufferXML_ReadFastArray(l);
01972 }
01973
01974
01975 void TBufferXML::ReadFastArray(Float_t *f, Int_t n)
01976 {
01977
01978
01979 TBufferXML_ReadFastArray(f);
01980 }
01981
01982
01983 void TBufferXML::ReadFastArray(Double_t *d, Int_t n)
01984 {
01985
01986
01987 TBufferXML_ReadFastArray(d);
01988 }
01989
01990
01991 void TBufferXML::ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement * )
01992 {
01993
01994
01995 TBufferXML_ReadFastArray(f);
01996 }
01997
01998
01999 void TBufferXML::ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement * )
02000 {
02001
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
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
02018
02019 TBufferFile::ReadFastArray(startp, cl, n, isPreAlloc, s, onFileClass);
02020 }
02021
02022
02023 #define TXMLWriteArrayNoncompress(vname, arrsize) \
02024 { \
02025 for(Int_t indx=0;indx<arrsize;indx++) \
02026 XmlWriteBasic(vname[indx]); \
02027 }
02028
02029
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
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
02066
02067 TBufferXML_WriteArray(b);
02068 }
02069
02070
02071 void TBufferXML::WriteArray(const Char_t *c, Int_t n)
02072 {
02073
02074
02075 TBufferXML_WriteArray(c);
02076 }
02077
02078
02079 void TBufferXML::WriteArray(const UChar_t *c, Int_t n)
02080 {
02081
02082
02083 TBufferXML_WriteArray(c);
02084 }
02085
02086
02087 void TBufferXML::WriteArray(const Short_t *h, Int_t n)
02088 {
02089
02090
02091 TBufferXML_WriteArray(h);
02092 }
02093
02094
02095 void TBufferXML::WriteArray(const UShort_t *h, Int_t n)
02096 {
02097
02098
02099 TBufferXML_WriteArray(h);
02100 }
02101
02102
02103 void TBufferXML::WriteArray(const Int_t *i, Int_t n)
02104 {
02105
02106
02107 TBufferXML_WriteArray(i);
02108 }
02109
02110
02111 void TBufferXML::WriteArray(const UInt_t *i, Int_t n)
02112 {
02113
02114
02115 TBufferXML_WriteArray(i);
02116 }
02117
02118
02119 void TBufferXML::WriteArray(const Long_t *l, Int_t n)
02120 {
02121
02122
02123 TBufferXML_WriteArray(l);
02124 }
02125
02126
02127 void TBufferXML::WriteArray(const ULong_t *l, Int_t n)
02128 {
02129
02130
02131 TBufferXML_WriteArray(l);
02132 }
02133
02134
02135 void TBufferXML::WriteArray(const Long64_t *l, Int_t n)
02136 {
02137
02138
02139 TBufferXML_WriteArray(l);
02140 }
02141
02142
02143 void TBufferXML::WriteArray(const ULong64_t *l, Int_t n)
02144 {
02145
02146
02147 TBufferXML_WriteArray(l);
02148 }
02149
02150
02151 void TBufferXML::WriteArray(const Float_t *f, Int_t n)
02152 {
02153
02154
02155 TBufferXML_WriteArray(f);
02156 }
02157
02158
02159 void TBufferXML::WriteArray(const Double_t *d, Int_t n)
02160 {
02161
02162
02163 TBufferXML_WriteArray(d);
02164 }
02165
02166
02167 void TBufferXML::WriteArrayFloat16(const Float_t *f, Int_t n, TStreamerElement * )
02168 {
02169
02170
02171 TBufferXML_WriteArray(f);
02172 }
02173
02174
02175 void TBufferXML::WriteArrayDouble32(const Double_t *d, Int_t n, TStreamerElement * )
02176 {
02177
02178
02179 TBufferXML_WriteArray(d);
02180 }
02181
02182
02183
02184
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
02227
02228 TBufferXML_WriteFastArray(b);
02229 }
02230
02231
02232 void TBufferXML::WriteFastArray(const Char_t *c, Int_t n)
02233 {
02234
02235
02236
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
02260
02261 TBufferXML_WriteFastArray(c);
02262 }
02263
02264
02265 void TBufferXML::WriteFastArray(const Short_t *h, Int_t n)
02266 {
02267
02268
02269 TBufferXML_WriteFastArray(h);
02270 }
02271
02272
02273 void TBufferXML::WriteFastArray(const UShort_t *h, Int_t n)
02274 {
02275
02276
02277 TBufferXML_WriteFastArray(h);
02278 }
02279
02280
02281 void TBufferXML::WriteFastArray(const Int_t *i, Int_t n)
02282 {
02283
02284
02285 TBufferXML_WriteFastArray(i);
02286 }
02287
02288
02289 void TBufferXML::WriteFastArray(const UInt_t *i, Int_t n)
02290 {
02291
02292
02293 TBufferXML_WriteFastArray(i);
02294 }
02295
02296
02297 void TBufferXML::WriteFastArray(const Long_t *l, Int_t n)
02298 {
02299
02300
02301 TBufferXML_WriteFastArray(l);
02302 }
02303
02304
02305 void TBufferXML::WriteFastArray(const ULong_t *l, Int_t n)
02306 {
02307
02308
02309 TBufferXML_WriteFastArray(l);
02310 }
02311
02312
02313 void TBufferXML::WriteFastArray(const Long64_t *l, Int_t n)
02314 {
02315
02316
02317 TBufferXML_WriteFastArray(l);
02318 }
02319
02320
02321 void TBufferXML::WriteFastArray(const ULong64_t *l, Int_t n)
02322 {
02323
02324
02325 TBufferXML_WriteFastArray(l);
02326 }
02327
02328
02329 void TBufferXML::WriteFastArray(const Float_t *f, Int_t n)
02330 {
02331
02332
02333 TBufferXML_WriteFastArray(f);
02334 }
02335
02336
02337 void TBufferXML::WriteFastArray(const Double_t *d, Int_t n)
02338 {
02339
02340
02341 TBufferXML_WriteFastArray(d);
02342 }
02343
02344
02345 void TBufferXML::WriteFastArrayFloat16(const Float_t *f, Int_t n, TStreamerElement * )
02346 {
02347
02348
02349 TBufferXML_WriteFastArray(f);
02350 }
02351
02352
02353 void TBufferXML::WriteFastArrayDouble32(const Double_t *d, Int_t n, TStreamerElement * )
02354 {
02355
02356
02357 TBufferXML_WriteFastArray(d);
02358 }
02359
02360
02361 void TBufferXML::WriteFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *s)
02362 {
02363
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
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* )
02378 {
02379
02380
02381 StreamObject(obj, TClass::GetClass(typeinfo));
02382 }
02383
02384
02385 void TBufferXML::StreamObject(void *obj, const char *className, const TClass* )
02386 {
02387
02388
02389 StreamObject(obj, TClass::GetClass(className));
02390 }
02391
02392 void TBufferXML::StreamObject(TObject *obj)
02393 {
02394
02395
02396 StreamObject(obj, obj ? obj->IsA() : TObject::Class());
02397 }
02398
02399
02400 void TBufferXML::StreamObject(void *obj, const TClass *cl, const TClass* )
02401 {
02402
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
02414 #define TBufferXML_operatorin(vname) \
02415 { \
02416 BeforeIOoperation(); \
02417 XmlReadBasic(vname); \
02418 }
02419
02420
02421 void TBufferXML::ReadBool(Bool_t &b)
02422 {
02423
02424
02425 TBufferXML_operatorin(b);
02426 }
02427
02428
02429 void TBufferXML::ReadChar(Char_t &c)
02430 {
02431
02432
02433 TBufferXML_operatorin(c);
02434 }
02435
02436
02437 void TBufferXML::ReadUChar(UChar_t &c)
02438 {
02439
02440
02441 TBufferXML_operatorin(c);
02442 }
02443
02444
02445 void TBufferXML::ReadShort(Short_t &h)
02446 {
02447
02448
02449 TBufferXML_operatorin(h);
02450 }
02451
02452
02453 void TBufferXML::ReadUShort(UShort_t &h)
02454 {
02455
02456
02457 TBufferXML_operatorin(h);
02458 }
02459
02460
02461 void TBufferXML::ReadInt(Int_t &i)
02462 {
02463
02464
02465 TBufferXML_operatorin(i);
02466 }
02467
02468
02469 void TBufferXML::ReadUInt(UInt_t &i)
02470 {
02471
02472
02473 TBufferXML_operatorin(i);
02474 }
02475
02476
02477 void TBufferXML::ReadLong(Long_t &l)
02478 {
02479
02480
02481 TBufferXML_operatorin(l);
02482 }
02483
02484
02485 void TBufferXML::ReadULong(ULong_t &l)
02486 {
02487
02488
02489 TBufferXML_operatorin(l);
02490 }
02491
02492
02493 void TBufferXML::ReadLong64(Long64_t &l)
02494 {
02495
02496
02497 TBufferXML_operatorin(l);
02498 }
02499
02500
02501 void TBufferXML::ReadULong64(ULong64_t &l)
02502 {
02503
02504
02505 TBufferXML_operatorin(l);
02506 }
02507
02508
02509 void TBufferXML::ReadFloat(Float_t &f)
02510 {
02511
02512
02513 TBufferXML_operatorin(f);
02514 }
02515
02516
02517 void TBufferXML::ReadDouble(Double_t &d)
02518 {
02519
02520
02521 TBufferXML_operatorin(d);
02522 }
02523
02524
02525 void TBufferXML::ReadCharP(Char_t *c)
02526 {
02527
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 & )
02537 {
02538
02539
02540
02541
02542
02543
02544 }
02545
02546
02547 #define TBufferXML_operatorout(vname) \
02548 { \
02549 BeforeIOoperation(); \
02550 XmlWriteBasic(vname); \
02551 }
02552
02553
02554 void TBufferXML::WriteBool(Bool_t b)
02555 {
02556
02557
02558 TBufferXML_operatorout(b);
02559 }
02560
02561
02562 void TBufferXML::WriteChar(Char_t c)
02563 {
02564
02565
02566 TBufferXML_operatorout(c);
02567 }
02568
02569
02570 void TBufferXML::WriteUChar(UChar_t c)
02571 {
02572
02573
02574 TBufferXML_operatorout(c);
02575 }
02576
02577
02578 void TBufferXML::WriteShort(Short_t h)
02579 {
02580
02581
02582 TBufferXML_operatorout(h);
02583 }
02584
02585
02586 void TBufferXML::WriteUShort(UShort_t h)
02587 {
02588
02589
02590 TBufferXML_operatorout(h);
02591 }
02592
02593
02594 void TBufferXML::WriteInt(Int_t i)
02595 {
02596
02597
02598 TBufferXML_operatorout(i);
02599 }
02600
02601
02602 void TBufferXML::WriteUInt(UInt_t i)
02603 {
02604
02605
02606 TBufferXML_operatorout(i);
02607 }
02608
02609
02610 void TBufferXML::WriteLong(Long_t l)
02611 {
02612
02613
02614 TBufferXML_operatorout(l);
02615 }
02616
02617
02618 void TBufferXML::WriteULong(ULong_t l)
02619 {
02620
02621
02622 TBufferXML_operatorout(l);
02623 }
02624
02625
02626 void TBufferXML::WriteLong64(Long64_t l)
02627 {
02628
02629
02630 TBufferXML_operatorout(l);
02631 }
02632
02633
02634 void TBufferXML::WriteULong64(ULong64_t l)
02635 {
02636
02637
02638 TBufferXML_operatorout(l);
02639 }
02640
02641
02642 void TBufferXML::WriteFloat(Float_t f)
02643 {
02644
02645
02646 TBufferXML_operatorout(f);
02647 }
02648
02649
02650 void TBufferXML::WriteDouble(Double_t d)
02651 {
02652
02653
02654 TBufferXML_operatorout(d);
02655 }
02656
02657
02658 void TBufferXML::WriteCharP(const Char_t *c)
02659 {
02660
02661
02662 BeforeIOoperation();
02663 XmlWriteValue(c, xmlio::CharStar);
02664 }
02665
02666
02667 void TBufferXML::WriteTString(const TString & )
02668 {
02669
02670
02671
02672
02673
02674 }
02675
02676
02677 XMLNodePointer_t TBufferXML::XmlWriteBasic(Char_t value)
02678 {
02679
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
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
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
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
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
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
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
02750
02751 return XmlWriteValue(value ? xmlio::True : xmlio::False, xmlio::Bool);
02752 }
02753
02754
02755 XMLNodePointer_t TBufferXML::XmlWriteBasic(UChar_t value)
02756 {
02757
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
03017
03018 if (fmt==0) fmt = "%e";
03019 fgFloatFmt = fmt;
03020 }
03021
03022 const char* TBufferXML::GetFloatFormat()
03023 {
03024
03025
03026 return fgFloatFmt;
03027 }
03028
03029
03030 Int_t TBufferXML::ReadSequence(const TStreamerInfoActions::TActionSequence &sequence, void *obj)
03031 {
03032
03033
03034
03035 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03036 IncrementLevel(info);
03037
03038 if (gDebug) {
03039
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
03045 SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03046 (*iter).PrintDebug(*this,obj);
03047 (*iter)(*this,obj);
03048 }
03049
03050 } else {
03051
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
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
03070
03071
03072 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03073 IncrementLevel(info);
03074
03075 if (gDebug) {
03076
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
03082 SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03083 (*iter).PrintDebug(*this,*(char**)start_collection);
03084 (*iter)(*this,start_collection,end_collection);
03085 }
03086
03087 } else {
03088
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
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
03107
03108 TVirtualStreamerInfo *info = sequence.fStreamerInfo;
03109 IncrementLevel(info);
03110
03111 TStreamerInfoActions::TLoopConfiguration *loopconfig = sequence.fLoopConfig;
03112 if (gDebug) {
03113
03114
03115
03116
03117 void *arr0 = loopconfig->GetFirstAddress(start_collection,end_collection);
03118
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
03124 SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03125 (*iter).PrintDebug(*this,arr0);
03126 (*iter)(*this,start_collection,end_collection,loopconfig);
03127 }
03128
03129 } else {
03130
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
03136 SetStreamerElementNumber((*iter).fConfiguration->fElemId);
03137 (*iter)(*this,start_collection,end_collection,loopconfig);
03138 }
03139 }
03140
03141 DecrementLevel(info);
03142 return 0;
03143 }