Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TStreamerInfoActions.cxx
Go to the documentation of this file.
1// @(#)root/io:$Id$
2// Author: Philippe Canal 05/2010
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12#include "TStreamerInfo.h"
14#include "TROOT.h"
15#include "TStreamerElement.h"
16#include "TVirtualMutex.h"
17#include "TInterpreter.h"
18#include "TError.h"
19#include "TVirtualArray.h"
20#include "TBufferFile.h"
21#include "TBufferText.h"
22#include "TMemberStreamer.h"
23#include "TClassEdit.h"
25#include "TProcessID.h"
26#include "TFile.h"
27
29
30// More possible optimizations:
31// Avoid call the virtual version of TBuffer::ReadInt and co.
32// Merge the Reading of the version and the looking up or the StreamerInfo
33// Avoid if (bytecnt) inside the CheckByteCount routines and avoid multiple (mostly useless nested calls)
34// Try to avoid if statement on onfile class being set (TBufferFile::ReadClassBuffer).
35
36using namespace TStreamerInfoActions;
37
38#ifdef _AIX
39# define INLINE_TEMPLATE_ARGS
40#else
41# define INLINE_TEMPLATE_ARGS inline
42#endif
43
44
46{
48 {
49 const auto props = proxy.GetProperties();
50 const bool isVector = proxy.GetCollectionType() == ROOT::kSTLvector;
51 const bool hasDefaultAlloc = !(props & TVirtualCollectionProxy::kCustomAlloc);
52 const bool isEmulated = props & TVirtualCollectionProxy::kIsEmulated;
53
54 return isEmulated || (isVector && hasDefaultAlloc);
55 }
56
57 template <typename From>
59 typedef From Value_t;
60 };
61
62 template <typename From>
64 typedef From Value_t;
65 };
66
67 struct BitsMarker {
68 typedef UInt_t Value_t;
69 };
70
72 {
73 // Add the (potentially negative) delta to all the configuration's offset. This is used by
74 // TBranchElement in the case of split sub-object.
75
77 fOffset += delta;
78 }
79
81 {
82 // Add the (potentially negative) delta to all the configuration's offset. This is used by
83 // TBranchElement in the case of split sub-object.
84
86 }
87
88 void TConfiguredAction::PrintDebug(TBuffer &buf, void *addr) const
89 {
90 // Inform the user what we are about to stream.
91
92 // Idea, we should find a way to print the name of the function
94 }
95
97 {
98 // Inform the user what we are about to stream.
99
101 TStreamerElement *aElement = fCompInfo->fElem;
102 TString sequenceType;
103 aElement->GetSequenceType(sequenceType);
104
105 printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
106 " %s, offset=%d (%s), elemnId=%d \n",
107 info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
108 aElement->ClassName(), fOffset, sequenceType.Data(), fElemId);
109 }
110
111 void TConfiguration::PrintDebug(TBuffer &buf, void *addr) const
112 {
113 // Inform the user what we are about to stream.
114
115 if (gDebug > 1) {
116 // Idea: We should print the name of the action function.
118 TStreamerElement *aElement = fCompInfo->fElem;
119 TString sequenceType;
120 aElement->GetSequenceType(sequenceType);
121
122 printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
123 " %s, bufpos=%d, arr=%p, offset=%d (%s)\n",
124 info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
125 aElement->ClassName(), buf.Length(), addr, fOffset, sequenceType.Data());
126 }
127 }
128
130 {
131 // Inform the user what we are about to stream.
132
133 printf("TLoopConfiguration: unconfigured\n");
134 }
135
136
138 // Configuration of action using the legacy code.
139 // Mostly to cancel out the PrintDebug.
140 public:
142 void PrintDebug(TBuffer &, void *) const override {
143 // Since we call the old code, it will print the debug statement.
144 }
145
146 TConfiguration *Copy() override { return new TGenericConfiguration(*this); }
147 };
148
150 // Configuration of action handling kBits.
151 // In this case we need to know both the location
152 // of the member (fBits) and the start of the object
153 // (its TObject part to be exact).
154
155 Int_t fObjectOffset; // Offset of the TObject part within the object
156
158 void PrintDebug(TBuffer &, void *) const override
159 {
161 TStreamerElement *aElement = fCompInfo->fElem;
162 TString sequenceType;
163 aElement->GetSequenceType(sequenceType);
164
165 printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
166 " %s, offset=%d (%s)\n",
167 info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
168 aElement->ClassName(), fOffset, sequenceType.Data());
169 }
170
171 void AddToOffset(Int_t delta) override
172 {
173 // Add the (potentially negative) delta to all the configuration's offset. This is used by
174 // TBranchElement in the case of split sub-object.
175
177 fOffset += delta;
178 fObjectOffset = 0;
179 }
180
181 void SetMissing() override
182 {
184 fObjectOffset = 0;
185 }
186
187 TConfiguration *Copy() override { return new TBitsConfiguration(*this); }
188
189 };
190
191 Int_t GenericReadAction(TBuffer &buf, void *addr, const TConfiguration *config)
192 {
193 char *obj = (char*)addr;
195 return ((TStreamerInfo*)conf->fInfo)->ReadBuffer(buf, &obj, &(conf->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ 1, config->fOffset, 2);
196 }
197
198 Int_t GenericWriteAction(TBuffer &buf, void *addr, const TConfiguration *config)
199 {
200 char *obj = (char*)addr;
202 return ((TStreamerInfo*)conf->fInfo)->WriteBufferAux(buf, &obj, &(conf->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ 1, config->fOffset, 2);
203 }
204
205 template <typename T>
207 {
208 T *x = (T*)( ((char*)addr) + config->fOffset );
209 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
210 buf >> *x;
211 return 0;
212 }
213
214 void HandleReferencedTObject(TBuffer &buf, void *addr, const TConfiguration *config) {
215 TBitsConfiguration *conf = (TBitsConfiguration*)config;
216 UShort_t pidf;
217 buf >> pidf;
218 pidf += buf.GetPidOffset();
219 TProcessID *pid = buf.ReadProcessID(pidf);
220 if (pid!=0) {
221 TObject *obj = (TObject*)( ((char*)addr) + conf->fObjectOffset);
222 UInt_t gpid = pid->GetUniqueID();
223 UInt_t uid;
224 if (gpid>=0xff) {
225 uid = obj->GetUniqueID() | 0xff000000;
226 } else {
227 uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
228 }
229 obj->SetUniqueID(uid);
230 pid->PutObjectWithID(obj);
231 }
232 }
233
234 template <>
236 {
237 UInt_t *x = (UInt_t*)( ((char*)addr) + config->fOffset );
238 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
239 // Idea: This code really belongs inside TBuffer[File]
240 const UInt_t isonheap = *x & TObject::kIsOnHeap; // Record how this instance was actually allocated.
241 buf >> *x;
242 *x |= isonheap | TObject::kNotDeleted; // by definition de-serialized object are not yet deleted.
243
244 if ((*x & kIsReferenced) != 0) {
245 HandleReferencedTObject(buf,addr,config);
246 }
247 return 0;
248 }
249
250 template <typename T>
252 {
253 T *x = (T *)(((char *)addr) + config->fOffset);
254 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
255 buf << *x;
256 return 0;
257 }
258
260 {
261 void *x = (void *)(((char *)addr) + config->fOffset);
262 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
264 return 0;
265 }
266
268 {
269 void *x = (void *)(((char *)addr) + config->fOffset);
270 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
272 return 0;
273 }
274
276 {
277 void *x = (void *)(((char *)addr) + config->fOffset);
278 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
279 ((TBufferText *)&buf)->WriteBaseClass(x, (TStreamerBase *)config->fCompInfo->fElem);
280 return 0;
281 }
282
284 {
285 void *x = (void *)(((char *)addr) + config->fOffset);
286 TMemberStreamer *pstreamer = config->fCompInfo->fStreamer;
287 UInt_t pos = buf.WriteVersion(config->fInfo->IsA(), kTRUE);
288 (*pstreamer)(buf, x, config->fCompInfo->fLength);
289 buf.SetByteCount(pos, kTRUE);
290 return 0;
291 }
292
294 {
295 void *x = (void *)(((char *)addr) + config->fOffset);
296 buf.ReadFastArray(x, config->fCompInfo->fClass, config->fCompInfo->fLength, config->fCompInfo->fStreamer);
297 return 0;
298 }
299
301 {
302 void *x = (void *)(((char *)addr) + config->fOffset);
304 return 0;
305 }
306
308 {
309 void *x = (void *)(((char *)addr) + config->fOffset);
310 // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
311 ((TBufferText *)&buf)->ReadBaseClass(x, (TStreamerBase *)config->fCompInfo->fElem);
312 return 0;
313 }
314
316 {
317 void *x = (void *)(((char *)addr) + config->fOffset);
318 TMemberStreamer *pstreamer = config->fCompInfo->fStreamer;
319
320 UInt_t start, count;
321 /* Version_t v = */ buf.ReadVersion(&start, &count, config->fCompInfo->fClass);
322 (*pstreamer)(buf, x, config->fCompInfo->fLength);
323 buf.CheckByteCount(start, count, config->fCompInfo->fElem->GetFullName());
324 return 0;
325 }
326
328 {
329 // action required to call custom code for TObject as base class
330 void *x = (void *)(((char *)addr) + config->fOffset);
332 return 0;
333 }
334
336 {
337 void *x = (void *)(((char *)addr) + config->fOffset);
339 return 0;
340 }
341
342 /** Direct copy of code from TStreamerInfo::WriteBufferAux,
343 * potentially can be used later for non-text streaming */
344 template<bool kIsTextT>
346 {
347 TClass *cl = config->fCompInfo->fClass;
348 TMemberStreamer *pstreamer = config->fCompInfo->fStreamer;
350 TClass* vClass = proxy ? proxy->GetValueClass() : 0;
351 UInt_t eoffset = 0; // extra parameter of TStreamerInfo::WriteBufferAux, 0 for all kind of objects writing
352 UInt_t ioffset = eoffset + config->fOffset;
353
355 && proxy && vClass
356 && config->fInfo->GetStreamMemberWise()
357 && cl->CanSplit()
358 && !(strspn(config->fCompInfo->fElem->GetTitle(),"||") == 2)
359 && !(vClass->HasCustomStreamerMember()) ) {
360 // Let's save the collection member-wise.
361
362 UInt_t pos = buf.WriteVersionMemberWise(config->fInfo->IsA(),kTRUE);
363 buf.WriteVersion( vClass, kFALSE );
364
365 // TODO: subinfo used for WriteBufferSTL call, which is private for the moment
366 //TStreamerInfo *subinfo = (TStreamerInfo*)vClass->GetStreamerInfo();
367
368 //for (int k = 0; k < narr; ++k) {
369 char **contp = (char **)((char *)addr + ioffset);
370 for(int j=0;j<config->fCompInfo->fLength;++j) {
371 char *cont = contp[j];
372 TVirtualCollectionProxy::TPushPop helper( proxy, cont );
373 Int_t nobjects = cont ? proxy->Size() : 0;
374 buf << nobjects;
375
376 // TODO: method is private, should be made accesible from here
377 // subinfo->WriteBufferSTL(buf,proxy,nobjects);
378 }
379 //}
380 buf.SetByteCount(pos,kTRUE);
381 return 0;
382 }
383 UInt_t pos = buf.WriteVersion(config->fInfo->IsA(), kTRUE);
384 if (kIsTextT) {
385 // use same method which is used in kSTL
386 buf.WriteFastArray((void **)((char *)addr + ioffset), cl, config->fCompInfo->fLength, kFALSE, pstreamer);
387 } else if (pstreamer == nullptr) {
388 // for (int k = 0; k < narr; ++k) {
389 char **contp = (char **)((char *)addr + ioffset);
390 for (int j = 0; j < config->fCompInfo->fLength; ++j) {
391 char *cont = contp[j];
392 cl->Streamer(cont, buf);
393 }
394 // }
395 } else {
396 // for (int k = 0; k < narr; ++k) {
397 (*pstreamer)(buf, (char *)addr + ioffset, config->fCompInfo->fLength);
398 //}
399 }
400 buf.SetByteCount(pos, kTRUE);
401 return 0;
402 }
403
404
405 /** Direct copy of code from TStreamerInfo::WriteBufferAux,
406 * potentially can be used later for non-text streaming */
407 template<bool kIsTextT>
409 {
410 TClass *cle = config->fCompInfo->fClass;
411 TStreamerElement * aElement = (TStreamerElement*) config->fCompInfo->fElem;
412 TMemberStreamer *pstreamer = config->fCompInfo->fStreamer;
413 //TVirtualCollectionProxy *proxy = cl->GetCollectionProxy();
414 //TClass* vClass = proxy ? proxy->GetValueClass() : 0;
415
416 UInt_t eoffset = 0; // extra parameter of TStreamerInfo::WriteBufferAux, 0 for all kind of objects writing
417 UInt_t ioffset = eoffset + config->fOffset;
418
419
420 UInt_t start,count;
421 Version_t vers = buf.ReadVersion(&start, &count, cle);
422
423 if (!kIsTextT && (vers & TBufferFile::kStreamedMemberWise) ) {
424 // Collection was saved member-wise
425
427
428 TClass *newClass = aElement->GetNewClass();
429 TClass *oldClass = aElement->GetClassPointer();
430 if( vers < 9 && newClass && newClass!=oldClass ) {
431 Error( "ReadBuffer", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s%s into a %s.",
432 vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass ? oldClass->GetName() : aElement->GetTypeName(), oldClass ? "" : " (could not find the corresponding TClass)", newClass->GetName() );
433 return 0;
434 }
435
436 Version_t vClVersion = 0; // For vers less than 9, we have to use the current version.
437 if( vers >= 9 ) {
438 vClVersion = buf.ReadVersionForMemberWise( cle->GetCollectionProxy()->GetValueClass() );
439 }
440
441 TVirtualCollectionProxy *newProxy = (newClass ? newClass->GetCollectionProxy() : nullptr);
442 TVirtualCollectionProxy *oldProxy = (oldClass ? oldClass->GetCollectionProxy() : nullptr);
443 TStreamerInfo *subinfo = nullptr;
444
445 if( newProxy ) {
446 // coverity[dereference] oldProxy->GetValueClass() can not be null since this was streamed memberwise.
447 subinfo = (TStreamerInfo*)newProxy->GetValueClass()->GetConversionStreamerInfo( oldProxy->GetValueClass(), vClVersion );
448 } else if ( oldProxy ) {
449 subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( vClVersion );
450 newProxy = oldProxy;
451 }
452 if (subinfo) {
453 // DOLOOP {
454 void* env;
455 void **contp = (void**)((char *) addr + ioffset);
456 for(int j=0;j<config->fCompInfo->fLength;j++) {
457 void *cont = contp[j];
458 if (cont==nullptr) {
459 contp[j] = cle->New();
460 cont = contp[j];
461 }
462 TVirtualCollectionProxy::TPushPop helper( newProxy, cont );
463 Int_t nobjects;
464 buf >> nobjects;
465 env = newProxy->Allocate(nobjects,true);
466 subinfo->ReadBufferSTL(buf,newProxy,nobjects,/* offset */ 0, vers>=7 );
467 newProxy->Commit(env);
468 }
469 // } // DOLOOP
470 }
471 buf.CheckByteCount(start,count,aElement->GetFullName());
472 return 0;
473 }
474
475 if (kIsTextT) {
476 // use same method which is used in kSTL
477 buf.ReadFastArray((void **)((char *)addr + ioffset), cle, config->fCompInfo->fLength, kFALSE, pstreamer);
478 } else if (pstreamer == nullptr) {
479 // DOLOOP {
480 void **contp = (void **)((char *)addr + ioffset);
481 for (int j = 0; j < config->fCompInfo->fLength; j++) {
482 void *cont = contp[j];
483 if (cont == nullptr) {
484 // int R__n;
485 // b >> R__n;
486 // b.SetOffset(b.GetOffset()-4); // rewind to the start of the int
487 // if (R__n) continue;
488 contp[j] = cle->New();
489 cont = contp[j];
490 }
491 cle->Streamer(cont, buf);
492 }
493 // }
494 } else {
495 (*pstreamer)(buf, (char *)addr + ioffset, config->fCompInfo->fLength);
496 }
497 buf.CheckByteCount(start, count, aElement->GetFullName());
498
499 return 0;
500 }
501
502 /** Direct copy of code from TStreamerInfo::WriteBufferAux,
503 * potentially can be used later for non-text streaming */
504 template<bool kIsTextT>
506 {
507 UInt_t eoffset = 0; // extra parameter of TStreamerInfo::WriteBufferAux, 0 for all kind of objects writing
508 UInt_t ioffset = eoffset + config->fOffset;
509
510 if (!kIsTextT && config->fCompInfo->fStreamer) {
511 // Get any private streamer which was set for the data member.
512 TMemberStreamer* pstreamer = config->fCompInfo->fStreamer;
513 // -- We have a private streamer.
514 UInt_t pos = buf.WriteVersion(config->fInfo->IsA(), kTRUE);
515 // Loop over the entries in the clones array or the STL container.
516 //for (int k = 0; k < narr; ++k) {
517 // Get a pointer to the counter for the varying length array.
518 Int_t* counter = (Int_t*) ((char *) addr /*entry pointer*/ + eoffset /*entry offset*/ + config->fCompInfo->fMethod /*counter offset*/);
519
520 // And call the private streamer, passing it the buffer, the object, and the counter.
521 (*pstreamer)(buf, (char *) addr /*entry pointer*/ + ioffset /*object offset*/, *counter);
522 //} for k
523 buf.SetByteCount(pos, kTRUE);
524 // We are done, next streamer element.
525 return 0;
526 }
527
528 // Get the class of the data member.
529 TClass* cl = config->fCompInfo->fClass;
530 // Which are we, an array of objects or an array of pointers to objects?
531 Bool_t isPtrPtr = (strstr(config->fCompInfo->fElem->GetTypeName(), "**") != 0);
532
533 // By default assume the file version is the newest.
534 Int_t fileVersion = kMaxInt;
535
536 if (!kIsTextT) {
537 // At this point we do *not* have a private streamer.
538 // Get the version of the file we are writing to.
539 TFile* file = (TFile*) buf.GetParent();
540 if (file) {
541 fileVersion = file->GetVersion();
542 }
543 }
544 // Write the class version to the buffer.
545 UInt_t pos = buf.WriteVersion(config->fInfo->IsA(), kTRUE);
546 if (fileVersion > 51508) {
547 // -- Newer versions allow polymorphic pointers to objects.
548 // Loop over the entries in the clones array or the STL container.
549 //for (int k = 0; k < narr; ++k) {
550 // Get the counter for the varying length array.
551 Int_t vlen = *((Int_t*) ((char *) addr /*entry pointer*/ + eoffset /*entry offset*/ + config->fCompInfo->fMethod /*counter offset*/));
552
553 //b << vlen;
554 if (vlen) {
555 // Get a pointer to the array of pointers.
556 char** pp = (char**) ((char *) addr /*entry pointer*/ + ioffset /*object offset*/);
557 // Loop over each element of the array of pointers to varying-length arrays.
558 for (Int_t ndx = 0; ndx < config->fCompInfo->fLength; ++ndx) {
559 if (!pp[ndx]) {
560 // -- We do not have a pointer to a varying-length array.
561 // Error("WriteBufferAux", "The pointer to element %s::%s type %d (%s) is null\n", GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
562 // ::ErrorHandler(kError, "::WriteStreamerLoop", Form("The pointer to element %s::%s type %d (%s) is null\n", config->fInfo->GetName(), config->fCompInfo->fElem->GetFullName(), config->fCompInfo->fType, config->fCompInfo->fElem->GetTypeName()));
563 printf("WriteStreamerLoop - The pointer to element %s::%s type %d (%s) is null\n", config->fInfo->GetName(), config->fCompInfo->fElem->GetFullName(), config->fCompInfo->fType, config->fCompInfo->fElem->GetTypeName());
564 continue;
565 }
566 if (!isPtrPtr) {
567 // -- We are a varying-length array of objects.
568 // Write the entire array of objects to the buffer.
569 // Note: Polymorphism is not allowed here.
570 buf.WriteFastArray(pp[ndx], cl, vlen, nullptr);
571 } else {
572 // -- We are a varying-length array of pointers to objects.
573 // Write the entire array of object pointers to the buffer.
574 // Note: The object pointers are allowed to be polymorphic.
575 buf.WriteFastArray((void **)pp[ndx], cl, vlen, kFALSE, nullptr);
576 } // isPtrPtr
577 } // ndx
578 } else // vlen
579 if (kIsTextT) {
580 // special handling for the text-based streamers
581 for (Int_t ndx = 0; ndx < config->fCompInfo->fLength; ++ndx)
582 buf.WriteFastArray((void *)nullptr, cl, -1, nullptr);
583 }
584 //} // k
585 }
586 else {
587 // -- Older versions do *not* allow polymorphic pointers to objects.
588 // Loop over the entries in the clones array or the STL container.
589 //for (int k = 0; k < narr; ++k) {
590 // Get the counter for the varying length array.
591 Int_t vlen = *((Int_t*) ((char *) addr /*entry pointer*/ + eoffset /*entry offset*/ + config->fCompInfo->fMethod /*counter offset*/));
592 //b << vlen;
593 if (vlen) {
594 // Get a pointer to the array of pointers.
595 char** pp = (char**) ((char *) addr /*entry pointer*/ + ioffset /*object offset*/);
596 // -- Older versions do *not* allow polymorphic pointers to objects.
597 // Loop over each element of the array of pointers to varying-length arrays.
598 for (Int_t ndx = 0; ndx < config->fCompInfo->fLength; ++ndx) {
599 if (!pp[ndx]) {
600 // -- We do not have a pointer to a varying-length array.
601 //Error("WriteBufferAux", "The pointer to element %s::%s type %d (%s) is null\n", GetName(), aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
602 // ::ErrorHandler(kError, "::WriteTextStreamerLoop", Form("The pointer to element %s::%s type %d (%s) is null\n", config->fInfo->GetName(), config->fCompInfo->fElem->GetFullName(), config->fCompInfo->fType, config->fCompInfo->fElem->GetTypeName()));
603 printf("WriteStreamerLoop - The pointer to element %s::%s type %d (%s) is null\n", config->fInfo->GetName(), config->fCompInfo->fElem->GetFullName(), config->fCompInfo->fType, config->fCompInfo->fElem->GetTypeName());
604 continue;
605 }
606 if (!isPtrPtr) {
607 // -- We are a varying-length array of objects.
608 // Loop over the elements of the varying length array.
609 for (Int_t v = 0; v < vlen; ++v) {
610 // Write the object to the buffer.
611 cl->Streamer(pp[ndx] + (v * cl->Size()), buf);
612 } // v
613 }
614 else {
615 // -- We are a varying-length array of pointers to objects.
616 // Loop over the elements of the varying length array.
617 for (Int_t v = 0; v < vlen; ++v) {
618 // Get a pointer to the object pointer.
619 char** r = (char**) pp[ndx];
620 // Write the object to the buffer.
621 cl->Streamer(r[v], buf);
622 } // v
623 } // isPtrPtr
624 } // ndx
625 } // vlen
626 //} // k
627 } // fileVersion
628 // Backpatch the byte count into the buffer.
629 buf.SetByteCount(pos, kTRUE);
630
631 return 0;
632 }
633
634
635 /** Direct copy of code from TStreamerInfo::WriteBufferAux,
636 * potentially can be used later for non-text streaming */
637 template<bool kIsTextT>
639 {
640 UInt_t eoffset = 0; // extra parameter of TStreamerInfo::WriteBufferAux, 0 for all kind of objects writing
641 UInt_t ioffset = eoffset + config->fOffset;
642
643 // Get the class of the data member.
644 TClass* cl = config->fCompInfo->fClass;
645
646 // Check for a private streamer.
647 if (!kIsTextT && config->fCompInfo->fStreamer) {
648 // Get any private streamer which was set for the data member.
649 TMemberStreamer* pstreamer = config->fCompInfo->fStreamer;
650 // -- We have a private streamer.
651 // Read the class version and byte count from the buffer.
652 UInt_t start = 0;
653 UInt_t count = 0;
654 buf.ReadVersion(&start, &count, cl);
655 // Loop over the entries in the clones array or the STL container.
656 //for (Int_t k = 0; k < narr; ++k) {
657
658 Int_t* counter = (Int_t*) ((char *) addr /*entry pointer*/ + eoffset /*entry offset*/ + config->fCompInfo->fMethod /*counter offset*/);
659 // And call the private streamer, passing it the buffer, the object, and the counter.
660 (*pstreamer)(buf, (char *) addr /*entry pointer*/ + ioffset /*object offset*/, *counter);
661
662 // } // for k
663 buf.CheckByteCount(start, count, config->fCompInfo->fElem->GetFullName());
664 // We are done, next streamer element.
665 return 0;
666 }
667
668 // Which are we, an array of objects or an array of pointers to objects?
669 Bool_t isPtrPtr = (strstr(config->fCompInfo->fElem->GetTypeName(), "**") != 0);
670
671 // By default assume the file version is the newest.
672 Int_t fileVersion = kMaxInt;
673 if (!kIsTextT) {
674 // At this point we do *not* have a private streamer.
675 // Get the version of the file we are reading from.
676 TFile* file = (TFile*) buf.GetParent();
677 if (file) {
678 fileVersion = file->GetVersion();
679 }
680 }
681 // Read the class version and byte count from the buffer.
682 UInt_t start = 0;
683 UInt_t count = 0;
684 buf.ReadVersion(&start, &count, cl);
685 if (fileVersion > 51508) {
686 // -- Newer versions allow polymorphic pointers.
687 // Loop over the entries in the clones array or the STL container.
688 // for (Int_t k = 0; k < narr; ++k) {
689 // Get the counter for the varying length array.
690 Int_t vlen = *((Int_t *)((char *)addr /*entry pointer*/ + eoffset /*entry offset*/ +
691 config->fCompInfo->fMethod /*counter offset*/));
692 // Int_t realLen;
693 // b >> realLen;
694 // if (realLen != vlen) {
695 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
696 //}
697 // Get a pointer to the array of pointers.
698 char **pp = (char **)((char *)addr /*entry pointer*/ + ioffset /*object offset*/);
699 // Loop over each element of the array of pointers to varying-length arrays.
700 // if (!pp) {
701 // continue;
702 // }
703
704 if (pp) // SL: place it here instead of continue, which is related to for(k) loop
705 for (Int_t ndx = 0; ndx < config->fCompInfo->fLength; ++ndx) {
706 // if (!pp[ndx]) {
707 // -- We do not have a pointer to a varying-length array.
708 // Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(),
709 // aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
710 // continue;
711 //}
712 // Delete any memory at pp[ndx].
713 if (!isPtrPtr) {
714 cl->DeleteArray(pp[ndx]);
715 pp[ndx] = 0;
716 } else {
717 // Using vlen is wrong here because it has already
718 // been overwritten with the value needed to read
719 // the current record. Fixing this will require
720 // doing a pass over the object at the beginning
721 // of the I/O and releasing all the buffer memory
722 // for varying length arrays before we overwrite
723 // the counter values.
724 //
725 // For now we will just leak memory, just as we
726 // have always done in the past. Fix this.
727 //
728 // char** r = (char**) pp[ndx];
729 // if (r) {
730 // for (Int_t v = 0; v < vlen; ++v) {
731 // cl->Destructor(r[v]);
732 // r[v] = 0;
733 // }
734 //}
735 delete[] pp[ndx];
736 pp[ndx] = 0;
737 }
738 if (!vlen) {
739 if (kIsTextT) {
740 // special handling for the text-based streamers - keep calling to shift array index
741 buf.ReadFastArray((void *)nullptr, cl, -1, nullptr);
742 }
743 continue;
744 }
745 // Note: We now have pp[ndx] is null.
746 // Allocate memory to read into.
747 if (!isPtrPtr) {
748 // -- We are a varying-length array of objects.
749 // Note: Polymorphism is not allowed here.
750 // Allocate a new array of objects to read into.
751 pp[ndx] = (char *)cl->NewArray(vlen);
752 if (!pp[ndx]) {
753 Error("ReadBuffer", "Memory allocation failed!\n");
754 continue;
755 }
756 } else {
757 // -- We are a varying-length array of pointers to objects.
758 // Note: The object pointers are allowed to be polymorphic.
759 // Allocate a new array of pointers to objects to read into.
760 pp[ndx] = (char *)new char *[vlen];
761 if (!pp[ndx]) {
762 Error("ReadBuffer", "Memory allocation failed!\n");
763 continue;
764 }
765 // And set each pointer to null.
766 memset(pp[ndx], 0, vlen * sizeof(char *)); // This is the right size we really have a char**: pp[ndx]
767 // = (char*) new char*[vlen];
768 }
769 if (!isPtrPtr) {
770 // -- We are a varying-length array of objects.
771 buf.ReadFastArray(pp[ndx], cl, vlen, nullptr);
772 } else {
773 // -- We are a varying-length array of object pointers.
774 buf.ReadFastArray((void **)pp[ndx], cl, vlen, kFALSE, nullptr);
775 } // isPtrPtr
776 } // ndx
777 // } // k
778 } else {
779 // -- Older versions do *not* allow polymorphic pointers.
780 // Loop over the entries in the clones array or the STL container.
781 // for (Int_t k = 0; k < narr; ++k) {
782 // Get the counter for the varying length array.
783 Int_t vlen = *((Int_t *)((char *)addr /*entry pointer*/ + eoffset /*entry offset*/ +
784 config->fCompInfo->fMethod /*counter offset*/));
785 // Int_t realLen;
786 // b >> realLen;
787 // if (realLen != vlen) {
788 // fprintf(stderr, "read vlen: %d realLen: %s\n", vlen, realLen);
789 //}
790 // Get a pointer to the array of pointers.
791 char **pp = (char **)((char *)addr /*entry pointer*/ + ioffset /*object offset*/);
792 // if (!pp) {
793 // continue;
794 //}
795
796 if (pp) // SL: place it here instead of continue, which is related to for(k) loop
797
798 // Loop over each element of the array of pointers to varying-length arrays.
799 for (Int_t ndx = 0; ndx < config->fCompInfo->fLength; ++ndx) {
800 // if (!pp[ndx]) {
801 // -- We do not have a pointer to a varying-length array.
802 // Error("ReadBuffer", "The pointer to element %s::%s type %d (%s) is null\n", thisVar->GetName(),
803 // aElement->GetFullName(), compinfo[i]->fType, aElement->GetTypeName());
804 // continue;
805 //}
806 // Delete any memory at pp[ndx].
807 if (!isPtrPtr) {
808 cl->DeleteArray(pp[ndx]);
809 pp[ndx] = 0;
810 } else {
811 // Using vlen is wrong here because it has already
812 // been overwritten with the value needed to read
813 // the current record. Fixing this will require
814 // doing a pass over the object at the beginning
815 // of the I/O and releasing all the buffer memory
816 // for varying length arrays before we overwrite
817 // the counter values.
818 //
819 // For now we will just leak memory, just as we
820 // have always done in the past. Fix this.
821 //
822 // char** r = (char**) pp[ndx];
823 // if (r) {
824 // for (Int_t v = 0; v < vlen; ++v) {
825 // cl->Destructor(r[v]);
826 // r[v] = 0;
827 // }
828 //}
829 delete[] pp[ndx];
830 pp[ndx] = 0;
831 }
832 if (!vlen) {
833 continue;
834 }
835 // Note: We now have pp[ndx] is null.
836 // Allocate memory to read into.
837 if (!isPtrPtr) {
838 // -- We are a varying-length array of objects.
839 // Note: Polymorphism is not allowed here.
840 // Allocate a new array of objects to read into.
841 pp[ndx] = (char *)cl->NewArray(vlen);
842 if (!pp[ndx]) {
843 Error("ReadBuffer", "Memory allocation failed!\n");
844 continue;
845 }
846 } else {
847 // -- We are a varying-length array of pointers to objects.
848 // Note: The object pointers are allowed to be polymorphic.
849 // Allocate a new array of pointers to objects to read into.
850 pp[ndx] = (char *)new char *[vlen];
851 if (!pp[ndx]) {
852 Error("ReadBuffer", "Memory allocation failed!\n");
853 continue;
854 }
855 // And set each pointer to null.
856 memset(pp[ndx], 0, vlen * sizeof(char *)); // This is the right size we really have a char**: pp[ndx]
857 // = (char*) new char*[vlen];
858 }
859 if (!isPtrPtr) {
860 // -- We are a varying-length array of objects.
861 // Loop over the elements of the varying length array.
862 for (Int_t v = 0; v < vlen; ++v) {
863 // Read the object from the buffer.
864 cl->Streamer(pp[ndx] + (v * cl->Size()), buf);
865 } // v
866 } else {
867 // -- We are a varying-length array of object pointers.
868 // Get a pointer to the object pointer array.
869 char **r = (char **)pp[ndx];
870 // Loop over the elements of the varying length array.
871 for (Int_t v = 0; v < vlen; ++v) {
872 // Allocate an object to read into.
873 r[v] = (char *)cl->New();
874 if (!r[v]) {
875 // Do not print a second error message here.
876 // Error("ReadBuffer", "Memory allocation failed!\n");
877 continue;
878 }
879 // Read the object from the buffer.
880 cl->Streamer(r[v], buf);
881 } // v
882 } // isPtrPtr
883 } // ndx
884 // } // k
885 } // fileVersion
886 buf.CheckByteCount(start, count, config->fCompInfo->fElem->GetFullName());
887 return 0;
888 }
889
891 // Configuration object for the Float16/Double32 where a factor has been specified.
892 public:
896 TConfiguration *Copy() override { return new TConfWithFactor(*this); }
897 };
898
899 template <typename T>
901 {
902 // Stream a Float16 or Double32 where a factor has been specified.
903 //a range was specified. We read an integer and convert it back to a double.
904
905 TConfWithFactor *conf = (TConfWithFactor *)config;
906 buf.ReadWithFactor((T*)( ((char*)addr) + config->fOffset ), conf->fFactor, conf->fXmin);
907 return 0;
908 }
909
911 // Configuration object for the Float16/Double32 where a factor has been specified.
912 public:
914 TConfNoFactor(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, Int_t nbits) : TConfiguration(info,id,compinfo,offset),fNbits(nbits) {};
915 TConfiguration *Copy() override { return new TConfNoFactor(*this); }
916 };
917
918 template <typename T>
920 {
921 // Stream a Float16 or Double32 where a factor has not been specified.
922
923 TConfNoFactor *conf = (TConfNoFactor *)config;
924 Int_t nbits = conf->fNbits;
925
926 buf.ReadWithNbits( (T*)( ((char*)addr) + config->fOffset ), nbits );
927 return 0;
928 }
929
931 {
932 // Read in a TString object.
933
934 // Idea: We could separate the TString Streamer in its two parts and
935 // avoid the if (buf.IsReading()) and try having it inlined.
936 ((TString*)(((char*)addr)+config->fOffset))->TString::Streamer(buf);
937 return 0;
938 }
939
941 {
942 // Read in a TObject object part.
943
944 // Idea: We could separate the TObject Streamer in its two parts and
945 // avoid the if (buf.IsReading()).
946 ((TObject*)(((char*)addr)+config->fOffset))->TObject::Streamer(buf);
947 return 0;
948 }
949
951 {
952 // Read in a TNamed object part.
953 // Since the TNamed streamer is solely delegating back to the StreamerInfo we
954 // can skip the streamer.
955
956 // Idea: We could extract the code from ReadClassBuffer and avoid one function
957 // code.
958 static const TClass *TNamed_cl = TNamed::Class();
959 return buf.ReadClassBuffer(TNamed_cl,(((char*)addr)+config->fOffset));
960 }
961
962 class TConfigSTL : public TConfiguration {
963 // Configuration object for the kSTL case
964 private:
965 void Init() {
967 if (proxy) {
973 }
974 }
975
976 public:
977 TClass *fOldClass; // Class of the content on file
978 TClass *fNewClass; // Class of the content in memory.
980 const char *fTypeName; // Type name of the member as typed by ther user.
981 Bool_t fIsSTLBase; // aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()
982
988
989 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, const char *type_name, Bool_t isbase) :
990 TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(oldClass), fStreamer(0), fTypeName(type_name), fIsSTLBase(isbase),
992
993 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, const char *type_name, Bool_t isbase) :
994 TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(newClass), fStreamer(0), fTypeName(type_name), fIsSTLBase(isbase),
996
997 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TMemberStreamer* streamer, const char *type_name, Bool_t isbase) :
998 TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(oldClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
1000
1001 TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, TMemberStreamer* streamer, const char *type_name, Bool_t isbase) :
1002 TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(newClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
1004
1005 TConfiguration *Copy() override { return new TConfigSTL(*this); }
1006 };
1007
1009 // Configuration object for the Float16/Double32 where a factor has been specified.
1010 public:
1014 TConfiguration *Copy() override { return new TConfSTLWithFactor(*this); }
1015 };
1016
1018 // Configuration object for the Float16/Double32 where a factor has been specified.
1019 public:
1021 TConfSTLNoFactor(TConfigSTL *orig, Int_t nbits) : TConfigSTL(*orig),fNbits(nbits) {};
1022 TConfiguration *Copy() override { return new TConfSTLNoFactor(*this); }
1023 };
1024
1026 // Base class of the Configurations used in member wise streaming.
1027 protected:
1028 public:
1029 Long_t fIncrement; // Either a value to increase the cursor by and
1030 public:
1031 TVectorLoopConfig(TVirtualCollectionProxy *proxy, Long_t increment, Bool_t /* read */) : TLoopConfiguration(proxy), fIncrement(increment) {};
1032 //virtual void PrintDebug(TBuffer &buffer, void *);
1033 ~TVectorLoopConfig() override {};
1034 void Print() const override
1035 {
1036 printf("TVectorLoopConfig: increment=%ld\n",fIncrement);
1037 }
1038
1039 void* GetFirstAddress(void *start, const void * /* end */) const override
1040 {
1041 // Return the address of the first element of the collection.
1042
1043 return start;
1044 }
1045
1046 TLoopConfiguration* Copy() const override { return new TVectorLoopConfig(*this); }
1047 };
1048
1050 // Base class of the Configurations used in member wise streaming.
1051 public:
1053 //virtual void PrintDebug(TBuffer &buffer, void *);
1054 ~TAssocLoopConfig() override {};
1055 void Print() const override
1056 {
1057 printf("TAssocLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
1058 }
1059 TLoopConfiguration* Copy() const override { return new TAssocLoopConfig(*this); }
1060
1061 void* GetFirstAddress(void *start, const void * /* end */) const override
1062 {
1063 // Return the address of the first element of the collection.
1064
1065 R__ASSERT(0);
1066// char iterator[TVirtualCollectionProxy::fgIteratorArenaSize];
1067// void *iter = genloopconfig->fCopyIterator(&iterator,start_collection);
1068// arr0 = genloopconfig->fNext(iter,end_collection);
1069// if (iter != &iterator[0]) {
1070// genloopconfig->fDeleteIterator(iter);
1071// }
1072 return start;
1073 }
1074 };
1075
1077 // Configuration object for the generic case of member wise streaming looping.
1078 private:
1079 void Init(Bool_t read) {
1080 if (fProxy) {
1081 if (fProxy->HasPointers()) {
1085 } else {
1086 fNext = fProxy->GetFunctionNext(read);
1089 }
1090 }
1091 }
1092 public:
1096
1098 {
1099 Init(read);
1100 }
1101 ~TGenericLoopConfig() override {};
1102 void Print() const override
1103 {
1104 printf("TGenericLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
1105 }
1106 TLoopConfiguration* Copy() const override { return new TGenericLoopConfig(*this); }
1107
1108 void* GetFirstAddress(void *start_collection, const void *end_collection) const override
1109 {
1110 // Return the address of the first element of the collection.
1111
1113 void *iter = fCopyIterator(&iterator,start_collection);
1114 void *arr0 = fNext(iter,end_collection);
1115 if (iter != &iterator[0]) {
1116 fDeleteIterator(iter);
1117 }
1118 return arr0;
1119 }
1120 };
1121
1123 {
1124 // Collection was saved member-wise
1125
1126 TConfigSTL *config = (TConfigSTL*)conf;
1128
1129 if( vers >= 8 ) {
1130
1131 TClass *oldClass = config->fOldClass;
1132
1133 TVirtualCollectionProxy *oldProxy = oldClass ? oldClass->GetCollectionProxy() : nullptr;
1134 if (!oldProxy) {
1135 // Missing information, broken file ... give up
1136 return;
1137 }
1138 TClass *valueClass = oldProxy->GetValueClass();
1139 Version_t vClVersion = buf.ReadVersionForMemberWise( valueClass );
1140
1141 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
1142 Int_t nobjects;
1143 buf.ReadInt(nobjects);
1144 void* alternative = oldProxy->Allocate(nobjects,true);
1145 if (nobjects) {
1146 TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
1147
1150 void *begin = &(startbuf[0]);
1151 void *end = &(endbuf[0]);
1152 config->fCreateIterators(alternative, &begin, &end, oldProxy);
1153 // We can not get here with a split vector of pointer, so we can indeed assume
1154 // that actions->fConfiguration != null.
1155 buf.ApplySequence(*actions, begin, end);
1156 if (begin != &(startbuf[0])) {
1157 // assert(end != endbuf);
1158 config->fDeleteTwoIterators(begin,end);
1159 }
1160 }
1161 oldProxy->Commit(alternative);
1162
1163 } else {
1164
1165 TClass *oldClass = config->fOldClass;
1166
1167 TVirtualCollectionProxy *oldProxy = oldClass ? oldClass->GetCollectionProxy() : nullptr;
1168 if (!oldProxy) {
1169 // Missing information, broken file ... give up
1170 return;
1171 }
1172
1173 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
1174 Int_t nobjects;
1175 buf.ReadInt(nobjects);
1176 void* env = oldProxy->Allocate(nobjects,true);
1177
1178 if (nobjects || vers < 7 ) {
1179 // coverity[dereference] since this is a member streaming action by definition the collection contains objects.
1180 TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
1181
1182 subinfo->ReadBufferSTL(buf, oldProxy, nobjects, /* offset */ 0, /* v7 */ kFALSE);
1183 }
1184 oldProxy->Commit(env);
1185 }
1186 }
1187
1189 {
1190 // Collection was saved member-wise
1191
1192 TConfigSTL *config = (TConfigSTL*)conf;
1194
1195 if( vers >= 8 ) {
1196
1197 TClass *oldClass = config->fOldClass;
1198
1199 TVirtualCollectionProxy *oldProxy = oldClass ? oldClass->GetCollectionProxy() : nullptr;
1200 if (!oldProxy) {
1201 // Missing information, broken file ... give up
1202 return;
1203 }
1204 TClass *valueClass = oldProxy->GetValueClass();
1205 Version_t vClVersion = buf.ReadVersionForMemberWise( valueClass );
1206
1207 TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
1208
1209 int objectSize = oldClass->Size();
1210 char *obj = (char*)addr;
1211 char *endobj = obj + conf->fLength*objectSize;
1212
1213 for(; obj<endobj; obj+=objectSize) {
1214 Int_t nobjects;
1215 buf.ReadInt(nobjects);
1216 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
1217 void* alternative = oldProxy->Allocate(nobjects,true);
1218 if (nobjects) {
1221 void *begin = &(startbuf[0]);
1222 void *end = &(endbuf[0]);
1223 config->fCreateIterators(alternative, &begin, &end, oldProxy);
1224 // We can not get here with a split vector of pointer, so we can indeed assume
1225 // that actions->fConfiguration != null.
1226 buf.ApplySequence(*actions, begin, end);
1227 if (begin != &(startbuf[0])) {
1228 // assert(end != endbuf);
1229 config->fDeleteTwoIterators(begin,end);
1230 }
1231 }
1232 oldProxy->Commit(alternative);
1233 }
1234
1235 } else {
1236
1237 TClass *oldClass = config->fOldClass;
1238
1239 TVirtualCollectionProxy *oldProxy = oldClass ? oldClass->GetCollectionProxy() : nullptr;
1240 if (!oldProxy) {
1241 // Missing information, broken file ... give up
1242 return;
1243 }
1244
1245 int objectSize = oldClass->Size();
1246 char *obj = (char*)addr;
1247 char *endobj = obj + conf->fLength*objectSize;
1248
1249 for(; obj<endobj; obj+=objectSize) {
1250 TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
1251 Int_t nobjects;
1252 buf.ReadInt(nobjects);
1253 void* env = oldProxy->Allocate(nobjects,true);
1254
1255 if (nobjects || vers < 7 ) {
1256 // coverity[dereference] since this is a member streaming action by definition the collection contains objects.
1257 TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
1258
1259 subinfo->ReadBufferSTL(buf, oldProxy, nobjects, /* offset */ 0, /* v7 */ kFALSE);
1260 }
1261 oldProxy->Commit(env);
1262 }
1263 }
1264 }
1265
1267 {
1268 // Collection was saved member-wise
1269
1270 TConfigSTL *config = (TConfigSTL*)conf;
1271
1273
1274 TClass *newClass = config->fNewClass;
1275 TClass *oldClass = config->fOldClass;
1276
1277 if( vers < 8 ) {
1278 Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1279 vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass ? oldClass->GetName() : "(could not find the origin TClass)", newClass ? newClass->GetName() : "(could not find the destination TClass)" );
1280 } else if (newClass && oldClass){
1281
1282 Version_t vClVersion = buf.ReadVersionForMemberWise( oldClass->GetCollectionProxy()->GetValueClass() );
1283
1284 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
1285 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1286
1287 TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)addr );
1288 Int_t nobjects;
1289 buf.ReadInt(nobjects);
1290 void* alternative = newProxy->Allocate(nobjects,true);
1291 if (nobjects) {
1292 TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
1295 void *begin = &(startbuf[0]);
1296 void *end = &(endbuf[0]);
1297 config->fCreateIterators( alternative, &begin, &end, newProxy);
1298 // We can not get here with a split vector of pointer, so we can indeed assume
1299 // that actions->fConfiguration != null.
1300 buf.ApplySequence(*actions, begin, end);
1301 if (begin != &(startbuf[0])) {
1302 // assert(end != endbuf);
1303 config->fDeleteTwoIterators(begin,end);
1304 }
1305 }
1306 newProxy->Commit(alternative);
1307 }
1308 }
1309
1311 {
1312 // Collection was saved member-wise
1313
1314 TConfigSTL *config = (TConfigSTL*)conf;
1315
1317
1318 TClass *newClass = config->fNewClass;
1319 TClass *oldClass = config->fOldClass;
1320
1321 if( vers < 8 ) {
1322 Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
1323 vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass ? oldClass->GetName() : "(could not find the origin TClass)", newClass ? newClass->GetName() : "(could not find the destination TClass)" );
1324 } else if (newClass && oldClass) {
1325
1326 Version_t vClVersion = buf.ReadVersionForMemberWise( oldClass->GetCollectionProxy()->GetValueClass() );
1327
1328 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
1329 TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
1330
1331 int objectSize = newClass->Size();
1332 char *obj = (char*)addr;
1333 char *endobj = obj + conf->fLength*objectSize;
1334
1335 for(; obj<endobj; obj+=objectSize) {
1336 TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)obj );
1337 Int_t nobjects;
1338 buf.ReadInt(nobjects);
1339 void* alternative = newProxy->Allocate(nobjects,true);
1340 if (nobjects) {
1341 TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
1344 void *begin = &(startbuf[0]);
1345 void *end = &(endbuf[0]);
1346 config->fCreateIterators( alternative, &begin, &end, newProxy);
1347 // We can not get here with a split vector of pointer, so we can indeed assume
1348 // that actions->fConfiguration != null.
1349 buf.ApplySequence(*actions, begin, end);
1350 if (begin != &(startbuf[0])) {
1351 // assert(end != endbuf);
1352 config->fDeleteTwoIterators(begin,end);
1353 }
1354 }
1355 newProxy->Commit(alternative);
1356 }
1357 }
1358 }
1359
1360 INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseFastArray(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t /* vers */, UInt_t /* start */)
1361 {
1362 TConfigSTL *config = (TConfigSTL*)conf;
1363 // Idea: This needs to be unrolled, it currently calls the TGenCollectionStreamer ....
1364 buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
1365 }
1366 INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t /* vers */, UInt_t /* start */)
1367 {
1368 TConfigSTL *config = (TConfigSTL*)conf;
1369 (*config->fStreamer)(buf,addr,conf->fLength);
1370 }
1372 {
1373 // case of old TStreamerInfo
1374
1375 TConfigSTL *config = (TConfigSTL*)conf;
1376 // Backward compatibility. Some TStreamerElement's where without
1377 // Streamer but were not removed from element list
1378 if (config->fIsSTLBase || vers == 0) {
1379 buf.SetBufferOffset(start); //there is no byte count
1380 }
1381 // Idea: This needs to be unrolled, it currently calls the TGenCollectionStreamer ....
1382 buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
1383 }
1385 {
1386 // case of old TStreamerInfo
1387
1388 TConfigSTL *config = (TConfigSTL*)conf;
1389 // Backward compatibility. Some TStreamerElement's where without
1390 // Streamer but were not removed from element list
1391 if (config->fIsSTLBase || vers == 0) {
1392 buf.SetBufferOffset(start); //there is no byte count
1393 }
1394 (*config->fStreamer)(buf,addr,conf->fLength);
1395 }
1396
1397 template <void (*memberwise)(TBuffer&,void *,const TConfiguration*, Version_t),
1398 void (*objectwise)(TBuffer&,void *,const TConfiguration*, Version_t, UInt_t)>
1400 {
1401 TConfigSTL *config = (TConfigSTL*)conf;
1402 UInt_t start, count;
1403 Version_t vers = buf.ReadVersion(&start, &count, config->fOldClass);
1404 if ( vers & TBufferFile::kStreamedMemberWise ) {
1405 memberwise(buf,((char*)addr)+config->fOffset,config, vers);
1406 } else {
1407 objectwise(buf,((char*)addr)+config->fOffset,config, vers, start);
1408 }
1409 buf.CheckByteCount(start,count,config->fTypeName);
1410 return 0;
1411 }
1412
1413 template <typename From, typename To>
1415 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
1416 {
1417 // Simple conversion from a 'From' on disk to a 'To' in memory.
1418 From temp;
1419 buf >> temp;
1420 *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
1421 return 0;
1422 }
1423 };
1424
1425 template <typename To>
1427 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
1428 {
1429 // Simple conversion from a 'From' on disk to a 'To' in memory
1430 UInt_t temp;
1431 buf >> temp;
1432
1433 if ((temp & kIsReferenced) != 0) {
1434 HandleReferencedTObject(buf,addr,config);
1435 }
1436
1437 *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
1438 return 0;
1439 }
1440 };
1441
1442 template <typename From, typename To>
1444 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
1445 {
1446 // Simple conversion from a 'From' on disk to a 'To' in memory.
1447 TConfWithFactor *conf = (TConfWithFactor *)config;
1448 From temp;
1449 buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
1450 *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
1451 return 0;
1452 }
1453 };
1454
1455 template <typename From, typename To>
1457 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
1458 {
1459 // Simple conversion from a 'From' on disk to a 'To' in memory.
1460 TConfNoFactor *conf = (TConfNoFactor *)config;
1461 From temp;
1462 buf.ReadWithNbits(&temp, conf->fNbits);
1463 *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
1464 return 0;
1465 }
1466 };
1467
1469 // Configuration object for the PushDataCache case.
1470 public:
1472
1474 TConfiguration(info, -1, nullptr, offset), fOnfileObject(onfileObject)
1475 {}
1476
1477 void Print() const override
1478 {
1480 if (fOnfileObject)
1481 printf("StreamerInfoAction, class:%s, PushDataCache offset=%d\n",
1482 info->GetClass()->GetName(), fOffset);
1483 else
1484 printf("StreamerInfoAction, class:%s, PopDataCache offset=%d\n",
1485 info->GetClass()->GetName(), fOffset);
1486 }
1487 void PrintDebug(TBuffer &buffer, void *object) const override
1488 {
1489 if (gDebug > 1) {
1491 printf("StreamerInfoAction, class:%s, %sDataCache, bufpos=%d, arr=%p, offset=%d, onfileObject=%p\n",
1492 info->GetClass()->GetName(), fOnfileObject ? "Push" : "Pop", buffer.Length(), object, fOffset, fOnfileObject);
1493
1494 }
1495 }
1496 };
1497
1499 {
1501 auto onfileObject = config->fOnfileObject;
1502
1503 // onfileObject->SetSize(1);
1504 b.PushDataCache( onfileObject );
1505
1506 return 0;
1507 }
1508
1509 Int_t PushDataCacheVectorPtr(TBuffer &b, void *, const void *, const TConfiguration *conf)
1510 {
1512 auto onfileObject = config->fOnfileObject;
1513
1514 // onfileObject->SetSize(n);
1515 b.PushDataCache( onfileObject );
1516
1517 return 0;
1518 }
1519
1520 Int_t PushDataCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
1521 {
1523 auto onfileObject = config->fOnfileObject;
1524
1525 TVirtualCollectionProxy *proxy = ((TGenericLoopConfig*)loopconfig)->fProxy;
1526 UInt_t n = proxy->Size();
1527
1528 onfileObject->SetSize(n);
1529 b.PushDataCache( onfileObject );
1530
1531 return 0;
1532 }
1533
1535 {
1536 b.PopDataCache();
1537 return 0;
1538 }
1539
1540 Int_t PopDataCacheVectorPtr(TBuffer &b, void *, const void *, const TConfiguration *)
1541 {
1542 b.PopDataCache();
1543 return 0;
1544 }
1545
1547 {
1548 b.PopDataCache();
1549 return 0;
1550 }
1551
1553 // Configuration object for the UseCache case.
1554 public:
1557
1559 TConfiguration(info,action.fConfiguration->fElemId,action.fConfiguration->fCompInfo,action.fConfiguration->fOffset),fAction(action),fNeedRepeat(repeat) {};
1560 void PrintDebug(TBuffer &b, void *addr) const override
1561 {
1562 if (gDebug > 1) {
1563 // Idea: We should print the name of the action function.
1565 TStreamerElement *aElement = fCompInfo->fElem;
1566 fprintf(stdout,"StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
1567 " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
1568 info->GetClass()->GetName(),aElement->GetName(),fElemId,fCompInfo->fType,
1569 aElement->ClassName(),b.Length(),addr, 0,b.PeekDataCache() ? b.PeekDataCache()->GetObjectAt(0) : 0);
1570 }
1571
1572 }
1575 {
1577 fAction.fConfiguration = copy->fAction.fConfiguration->Copy(); // since the previous allocation did a 'move' of fAction we need to fix it.
1578 return copy;
1579 }
1580 };
1581
1583 {
1585
1586 Int_t bufpos = b.Length();
1587 TVirtualArray *cached = b.PeekDataCache();
1588 if (cached==0) {
1589 TStreamerElement *aElement = conf->fCompInfo->fElem;
1590 TStreamerInfo *info = (TStreamerInfo*)conf->fInfo;
1591 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
1592 char *ptr = (char*)addr;
1593 info->ReadBufferSkip(b,&ptr,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,1,0);
1594 } else {
1595 config->fAction(b, (*cached)[0]);
1596 }
1597 // Idea: Factor out this 'if' to a UseCacheRepeat function
1598 if (config->fNeedRepeat) {
1599 b.SetBufferOffset(bufpos);
1600 }
1601 return 0;
1602 }
1603
1604 INLINE_TEMPLATE_ARGS Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
1605 {
1607 Int_t bufpos = b.Length();
1608
1609 TVirtualArray *cached = b.PeekDataCache();
1610 if (cached==0) {
1611 TStreamerElement *aElement = config->fCompInfo->fElem;
1612 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
1613 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
1614 char *ptr = (char*)start;
1615 UInt_t n = (((void**)end)-((void**)start));
1616 info->ReadBufferSkip(b,&ptr,config->fCompInfo,conf->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
1617 } else {
1618 TVectorLoopConfig cached_config( nullptr, cached->fClass->Size(), /* read */ kTRUE );
1619 void *cached_start = (*cached)[0];
1620 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
1621 config->fAction(b,cached_start,cached_end,&cached_config);
1622 }
1623 // Idea: Factor out this 'if' to a UseCacheRepeat function
1624 if (config->fNeedRepeat) {
1625 b.SetBufferOffset(bufpos);
1626 }
1627 return 0;
1628 }
1629
1630 INLINE_TEMPLATE_ARGS Int_t UseCacheVectorLoop(TBuffer &b, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf)
1631 {
1633
1634 Int_t bufpos = b.Length();
1635 TVirtualArray *cached = b.PeekDataCache();
1636 if (cached==0) {
1637 TStreamerElement *aElement = config->fCompInfo->fElem;
1638 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
1639 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
1640 char *ptr = (char*)start;
1641 UInt_t n = (((char*)end)-((char*)start))/((TVectorLoopConfig*)loopconf)->fIncrement;
1642 info->ReadBufferSkip(b,&ptr,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
1643 } else {
1644 TVectorLoopConfig cached_config( nullptr, cached->fClass->Size(), /* read */ kTRUE );
1645 void *cached_start = (*cached)[0];
1646 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
1647 config->fAction(b,cached_start,cached_end,&cached_config);
1648 }
1649 // Idea: Factor out this 'if' to a UseCacheRepeat function
1650 if (config->fNeedRepeat) {
1651 b.SetBufferOffset(bufpos);
1652 }
1653 return 0;
1654 }
1655
1657 {
1659
1660 Int_t bufpos = b.Length();
1661 TVirtualArray *cached = b.PeekDataCache();
1662 if (cached==0) {
1663 TStreamerElement *aElement = config->fCompInfo->fElem;
1664 TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
1665
1666 TVirtualCollectionProxy *proxy = ((TGenericLoopConfig*)loopconfig)->fProxy;
1667 Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
1668 UInt_t n = proxy->Size();
1669 info->ReadBufferSkip(b, *proxy,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
1670 } else {
1671 TVectorLoopConfig cached_config( nullptr, cached->fClass->Size(), /* read */ kTRUE );
1672 void *cached_start = (*cached)[0];
1673 void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
1674 config->fAction(b,cached_start,cached_end,&cached_config);
1675 }
1676 // Idea: Factor out this 'if' to a UseCacheRepeat function
1677 if (config->fNeedRepeat) {
1678 b.SetBufferOffset(bufpos);
1679 }
1680 return 0;
1681 }
1682
1683 // Support for collections.
1684
1685 Int_t ReadLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
1686 {
1687 Fatal("ApplySequence","The sequence of actions to read %s:%d member-wise was not initialized.",config->fInfo->GetName(),config->fInfo->GetClassVersion());
1688 return 0;
1689 }
1690
1691 Int_t WriteLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
1692 {
1693 Fatal("ApplySequence","The sequence of actions to write %s:%d member-wise was not initialized.",config->fInfo->GetName(),config->fInfo->GetClassVersion());
1694 return 0;
1695 }
1696
1698
1700 {
1702 return kVectorLooper;
1703 } else if ( (proxy.GetCollectionType() == ROOT::kSTLvector)) {
1705 return kGenericLooper;
1706 else
1707 return kVectorLooper;
1712 || proxy.GetCollectionType() == ROOT::kSTLbitset) {
1713 return kAssociativeLooper;
1714 } else {
1715 return kGenericLooper;
1716 }
1717 }
1718
1720
1721 template <typename T>
1722 static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1723 {
1724 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1725 iter = (char*)iter + config->fOffset;
1726 end = (char*)end + config->fOffset;
1727 for(; iter != end; iter = (char*)iter + incr ) {
1728 T *x = (T*) ((char*) iter);
1729 buf >> *x;
1730 }
1731 return 0;
1732 }
1733
1734 template <typename From, typename To>
1736 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1737 {
1738 // Simple conversion from a 'From' on disk to a 'To' in memory.
1739 From temp;
1740 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1741 iter = (char*)iter + config->fOffset;
1742 end = (char*)end + config->fOffset;
1743 for(; iter != end; iter = (char*)iter + incr ) {
1744 buf >> temp;
1745 *(To*)( ((char*)iter) ) = (To)temp;
1746 }
1747 return 0;
1748 }
1749 };
1750
1751 template <typename To>
1753 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1754 {
1755 // Simple conversion from a 'From' on disk to a 'To' in memory.
1756 UInt_t temp;
1757 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1758 iter = (char*)iter + config->fOffset;
1759 end = (char*)end + config->fOffset;
1760 for(; iter != end; iter = (char*)iter + incr ) {
1761 buf >> temp;
1762
1763 if ((temp & kIsReferenced) != 0) {
1764 HandleReferencedTObject(buf, (char*)iter - config->fOffset, config);
1765 }
1766
1767 *(To*)( ((char*)iter) ) = (To)temp;
1768 }
1769 return 0;
1770 }
1771 };
1772
1773 template <typename From, typename To>
1775 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1776 {
1777 // Simple conversion from a 'From' on disk to a 'To' in memory.
1778 TConfWithFactor *conf = (TConfWithFactor *)config;
1779 From temp;
1780 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1781 iter = (char*)iter + config->fOffset;
1782 end = (char*)end + config->fOffset;
1783 for(; iter != end; iter = (char*)iter + incr ) {
1784 buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
1785 *(To*)( ((char*)iter) ) = (To)temp;
1786 }
1787 return 0;
1788 }
1789 };
1790
1791 template <typename From, typename To>
1793 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1794 {
1795 // Simple conversion from a 'From' on disk to a 'To' in memory.
1796 TConfNoFactor *conf = (TConfNoFactor *)config;
1797 From temp;
1798 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1799 iter = (char*)iter + config->fOffset;
1800 end = (char*)end + config->fOffset;
1801 for(; iter != end; iter = (char*)iter + incr ) {
1802 buf.ReadWithNbits(&temp, conf->fNbits);
1803 *(To*)( ((char*)iter) ) = (To)temp;
1804 }
1805 return 0;
1806 }
1807 };
1808
1809 template <typename T>
1810 static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1811 {
1812 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1813 iter = (char*)iter + config->fOffset;
1814 end = (char*)end + config->fOffset;
1815 for(; iter != end; iter = (char*)iter + incr ) {
1816 T *x = (T*) ((char*) iter);
1817 buf << *x;
1818 }
1819 return 0;
1820 }
1821
1822 template <Int_t (*iter_action)(TBuffer&,void *,const TConfiguration*)>
1823 static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1824 {
1825 const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1826 //Idea: can we factor out the addition of fOffset
1827 // iter = (char*)iter + config->fOffset;
1828 for(void *iter = start; iter != end; iter = (char*)iter + incr ) {
1829 iter_action(buf, iter, config);
1830 }
1831 return 0;
1832 }
1833
1834 static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1835 {
1836 // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
1837 // punt.
1838
1839 UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1840 UInt_t n = (((char*)end)-((char*)start))/incr;
1841 char **arrptr = new char*[n];
1842 UInt_t i = 0;
1843 for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1844 arrptr[i] = (char*)iter;
1845 }
1846 ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
1847 delete [] arrptr;
1848
1849 // // Idea: need to cache this result!
1850 // TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
1851 // TStreamerElement *aElement = (TStreamerElement*)info->GetElem(config->fElemId);
1852 //
1853 // *Int_t clversion = ((TStreamerBase*)aElement)->Get BaseVersion();
1854 // *TClass *cle = aElement->GetNewBaseClass();
1855 // *(TSequence *actions = CreateReadMemberWiseActions( cle->GetStreamerInfo(clversion), ???? );
1856 //
1857 // TSequence *actions = CreateReadMemberWiseActions( ((TStreamerBase*)aElement)->GetBaseStreamerInfo(), ???? );
1858 //
1859 // actions->ReadBuffer(b,start,end);
1860 // delete actions;
1861
1862 // const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1863 // for(void *iter = start; iter != end; iter = (char*)iter + incr )
1864 // {
1865 // ((TStreamerInfo*)(((TStreamerBase*)aElement)->GetBaseStreamerInfo())->ReadBuffer(b,arr,-1,narr,ioffset,arrayMode);
1866 //
1867 // ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, (char**)&iter, config->fElemId, 1, config->fOffset, 1|2 );
1868 // }
1869 return 0;
1870 }
1871
1872 static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1873 {
1874 // Well the implementation is non trivial. For now punt.
1875
1876 UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1877 UInt_t n = (((char*)end)-((char*)start))/incr;
1878 char **arrptr = new char*[n];
1879 UInt_t i = 0;
1880 for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1881 arrptr[i] = (char*)iter;
1882 }
1883 ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
1884 delete [] arrptr;
1885 return 0;
1886 }
1887
1888 static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1889 {
1890 // Well the implementation is non trivial. For now punt.
1891
1892 UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1893 UInt_t n = (((char*)end)-((char*)start))/incr;
1894 char **arrptr = new char*[n];
1895 UInt_t i = 0;
1896 for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1897 arrptr[i] = (char*)iter;
1898 }
1899 ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, n, config->fOffset, 1|2 );
1900 delete [] arrptr;
1901 return 0;
1902 }
1903
1904 template <typename T>
1906 {
1907 // Collection of numbers. Memberwise or not, it is all the same.
1908
1909 TConfigSTL *config = (TConfigSTL*)conf;
1910 UInt_t start, count;
1911 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1912
1913 std::vector<T> *const vec = (std::vector<T>*)(((char*)addr)+config->fOffset);
1914 Int_t nvalues;
1915 buf.ReadInt(nvalues);
1916 vec->resize(nvalues);
1917
1918#ifdef R__VISUAL_CPLUSPLUS
1919 if (nvalues <= 0) {
1920 buf.CheckByteCount(start,count,config->fTypeName);
1921 return 0;
1922 }
1923#endif
1924 T *begin = &(*vec->begin());
1925 buf.ReadFastArray(begin, nvalues);
1926
1927 buf.CheckByteCount(start,count,config->fTypeName);
1928 return 0;
1929 }
1930
1931
1933 {
1934 // Collection of numbers. Memberwise or not, it is all the same.
1935
1936 TConfigSTL *config = (TConfigSTL*)conf;
1937 UInt_t start, count;
1938 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1939
1940 std::vector<float> *const vec = (std::vector<float>*)(((char*)addr)+config->fOffset);
1941 Int_t nvalues;
1942 buf.ReadInt(nvalues);
1943 vec->resize(nvalues);
1944
1945#ifdef R__VISUAL_CPLUSPLUS
1946 if (nvalues <= 0) {
1947 buf.CheckByteCount(start,count,config->fTypeName);
1948 return 0;
1949 }
1950#endif
1951 float *begin = &(*vec->begin());
1952 buf.ReadFastArrayFloat16(begin, nvalues);
1953
1954 buf.CheckByteCount(start,count,config->fTypeName);
1955 return 0;
1956 }
1957
1959 {
1960 // Collection of numbers. Memberwise or not, it is all the same.
1961
1962 TConfigSTL *config = (TConfigSTL*)conf;
1963 UInt_t start, count;
1964 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1965
1966 std::vector<double> *const vec = (std::vector<double>*)(((char*)addr)+config->fOffset);
1967 Int_t nvalues;
1968 buf.ReadInt(nvalues);
1969 vec->resize(nvalues);
1970
1971#ifdef R__VISUAL_CPLUSPLUS
1972 if (nvalues <= 0) {
1973 buf.CheckByteCount(start,count,config->fTypeName);
1974 return 0;
1975 }
1976#endif
1977 double *begin = &(*vec->begin());
1978 buf.ReadFastArrayDouble32(begin, nvalues);
1979
1980 buf.CheckByteCount(start,count,config->fTypeName);
1981 return 0;
1982 }
1983
1984 template <typename From, typename To>
1986 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
1987 {
1988 // Collection of numbers. Memberwise or not, it is all the same.
1989
1990 TConfigSTL *config = (TConfigSTL*)conf;
1991 UInt_t start, count;
1992 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1993
1994 std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
1995 Int_t nvalues;
1996 buf.ReadInt(nvalues);
1997 vec->resize(nvalues);
1998
1999 From *temp = new From[nvalues];
2000 buf.ReadFastArray(temp, nvalues);
2001 for(Int_t ind = 0; ind < nvalues; ++ind) {
2002 (*vec)[ind] = (To)temp[ind];
2003 }
2004 delete [] temp;
2005
2006 buf.CheckByteCount(start,count,config->fTypeName);
2007 return 0;
2008 }
2009 };
2010
2011 template <typename From, typename To>
2013 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
2014 {
2015 // Collection of numbers. Memberwise or not, it is all the same.
2016
2017 TConfigSTL *config = (TConfigSTL*)conf;
2018 UInt_t start, count;
2019 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
2020
2021 std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
2022 Int_t nvalues;
2023 buf.ReadInt(nvalues);
2024 vec->resize(nvalues);
2025
2026 From *temp = new From[nvalues];
2027 buf.ReadFastArrayWithNbits(temp, nvalues, 0);
2028 for(Int_t ind = 0; ind < nvalues; ++ind) {
2029 (*vec)[ind] = (To)temp[ind];
2030 }
2031 delete [] temp;
2032
2033 buf.CheckByteCount(start,count,config->fTypeName);
2034 return 0;
2035 }
2036 };
2037
2038 template <typename To>
2040 {
2041 // Collection of numbers. Memberwise or not, it is all the same.
2042
2043 TConfigSTL *config = (TConfigSTL*)conf;
2044 UInt_t start, count;
2045 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
2046
2047 std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
2048 Int_t nvalues;
2049 buf.ReadInt(nvalues);
2050 vec->resize(nvalues);
2051
2052 Double32_t *temp = new Double32_t[nvalues];
2053 buf.ReadFastArrayDouble32(temp, nvalues);
2054 for(Int_t ind = 0; ind < nvalues; ++ind) {
2055 (*vec)[ind] = (To)temp[ind];
2056 }
2057 delete [] temp;
2058
2059 buf.CheckByteCount(start,count,config->fTypeName);
2060 return 0;
2061 }
2062
2063 };
2064
2066
2067 template <typename T>
2068 static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2069 {
2070 const Int_t offset = config->fOffset;
2071
2072 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2073 T *x = (T*)( ((char*) (*(void**)iter) ) + offset );
2074 buf >> *x;
2075 }
2076 return 0;
2077 }
2078
2079 template <typename From, typename To>
2081 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2082 {
2083 // Simple conversion from a 'From' on disk to a 'To' in memory.
2084 From temp;
2085 const Int_t offset = config->fOffset;
2086 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2087 buf >> temp;
2088 To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
2089 *x = (To)temp;
2090 }
2091 return 0;
2092 }
2093 };
2094
2095 template <typename To>
2097 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2098 {
2099 // Simple conversion from a 'From' on disk to a 'To' in memory.
2100 UInt_t temp;
2101 const Int_t offset = config->fOffset;
2102 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2103 buf >> temp;
2104
2105 if ((temp & kIsReferenced) != 0) {
2106 HandleReferencedTObject(buf,*(void**)iter,config);
2107 }
2108
2109 To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
2110 *x = (To)temp;
2111 }
2112 return 0;
2113 }
2114 };
2115
2116 template <typename From, typename To>
2118 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2119 {
2120 // Simple conversion from a 'From' on disk to a 'To' in memory.
2121 TConfWithFactor *conf = (TConfWithFactor *)config;
2122 From temp;
2123 const Int_t offset = config->fOffset;
2124 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2125 buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
2126 To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
2127 *x = (To)temp;
2128 }
2129 return 0;
2130 }
2131 };
2132
2133 template <typename From, typename To>
2135 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2136 {
2137 // Simple conversion from a 'From' on disk to a 'To' in memory.
2138 TConfNoFactor *conf = (TConfNoFactor *)config;
2139 From temp;
2140 const Int_t offset = config->fOffset;
2141 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2142 buf.ReadWithNbits(&temp, conf->fNbits);
2143 To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
2144 *x = (To)temp;
2145 }
2146 return 0;
2147 }
2148 };
2149
2150 template <typename T>
2151 static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2152 {
2153 const Int_t offset = config->fOffset;
2154
2155 for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
2156 T *x = (T*)( ((char*) (*(void**)iter) ) + offset );
2157 buf << *x;
2158 }
2159 return 0;
2160 }
2161
2162 template <Int_t (*action)(TBuffer&,void *,const TConfiguration*)>
2163 static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
2164 {
2165 for(void *iter = start; iter != end; iter = (char*)iter + sizeof(void*) ) {
2166 action(buf, *(void**)iter, config);
2167 }
2168 return 0;
2169 }
2170
2171 static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
2172 {
2173 // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
2174 // punt.
2175
2176 return GenericRead(buf,start,end,config);
2177 }
2178
2179 static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2180 {
2181 Int_t n = ( ((void**)end) - ((void**)iter) );
2182 char **arr = (char**)iter;
2183 return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
2184 }
2185
2186 static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
2187 {
2188 Int_t n = ( ((void**)end) - ((void**)iter) );
2189 char **arr = (char**)iter;
2190 return ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, arr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, n, config->fOffset, 1|2 );
2191 }
2192
2193 };
2194
2196
2197 template <typename T>
2198 static INLINE_TEMPLATE_ARGS void SimpleRead(TBuffer &buf, void *addr, Int_t nvalues)
2199 {
2200 buf.ReadFastArray((T*)addr, nvalues);
2201 }
2202
2203 static INLINE_TEMPLATE_ARGS void SimpleReadFloat16(TBuffer &buf, void *addr, Int_t nvalues)
2204 {
2205 buf.ReadFastArrayFloat16((float*)addr, nvalues);
2206 }
2207
2208 static INLINE_TEMPLATE_ARGS void SimpleReadDouble32(TBuffer &buf, void *addr, Int_t nvalues)
2209 {
2210 buf.ReadFastArrayDouble32((double*)addr, nvalues);
2211 }
2212
2213 template <typename T,void (*action)(TBuffer&,void *,Int_t)>
2215 {
2216 // Collection of numbers. Memberwise or not, it is all the same.
2217
2218 TConfigSTL *config = (TConfigSTL*)conf;
2219 UInt_t start, count;
2220 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
2221
2222 TClass *newClass = config->fNewClass;
2223 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
2224 TVirtualCollectionProxy::TPushPop helper( newProxy, ((char*)addr)+config->fOffset );
2225
2226 Int_t nvalues;
2227 buf.ReadInt(nvalues);
2228 void* alternative = newProxy->Allocate(nvalues,true);
2229 if (nvalues) {
2232 void *begin = &(startbuf[0]);
2233 void *end = &(endbuf[0]);
2234 config->fCreateIterators(alternative, &begin, &end, newProxy);
2235 // We can not get here with a split vector of pointer, so we can indeed assume
2236 // that actions->fConfiguration != null.
2237
2238 action(buf,begin,nvalues);
2239
2240 if (begin != &(startbuf[0])) {
2241 // assert(end != endbuf);
2242 config->fDeleteTwoIterators(begin,end);
2243 }
2244 }
2245 newProxy->Commit(alternative);
2246
2247 buf.CheckByteCount(start,count,config->fTypeName);
2248 return 0;
2249 }
2250
2252 {
2253 return ReadNumericalCollection<Float_t,SimpleReadFloat16 >(buf,addr,conf);
2254 }
2255
2257 {
2258 return ReadNumericalCollection<Double_t,SimpleReadDouble32 >(buf,addr,conf);
2259 }
2260
2261 template <typename T>
2263 {
2264 return ReadNumericalCollection<T,SimpleRead<T> >(buf,addr,conf);
2265 }
2266
2267 template <typename From, typename To>
2269 static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
2270 {
2271 From *temp = new From[nvalues];
2272 buf.ReadFastArray(temp, nvalues);
2273 To *vec = (To*)addr;
2274 for(Int_t ind = 0; ind < nvalues; ++ind) {
2275 vec[ind] = (To)temp[ind];
2276 }
2277 delete [] temp;
2278 }
2279 };
2280
2281 template <typename From, typename To>
2282 struct ConvertRead<NoFactorMarker<From>,To> {
2283 static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
2284 {
2285 From *temp = new From[nvalues];
2286 buf.ReadFastArrayWithNbits(temp, nvalues,0);
2287 To *vec = (To*)addr;
2288 for(Int_t ind = 0; ind < nvalues; ++ind) {
2289 vec[ind] = (To)temp[ind];
2290 }
2291 delete [] temp;
2292 }
2293 };
2294
2295 template <typename From, typename To>
2297 static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
2298 {
2299 From *temp = new From[nvalues];
2300 double factor,min; // needs to be initialized.
2301 buf.ReadFastArrayWithFactor(temp, nvalues, factor, min);
2302 To *vec = (To*)addr;
2303 for(Int_t ind = 0; ind < nvalues; ++ind) {
2304 vec[ind] = (To)temp[ind];
2305 }
2306 delete [] temp;
2307 }
2308 };
2309
2310 template <typename From, typename To>
2312 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
2313 {
2314 return ReadNumericalCollection<To,ConvertRead<From,To>::Action >(buf,addr,conf);
2315 }
2316 };
2317
2318 };
2319
2321
2322 template <typename T>
2323 static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2324 {
2325 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2326
2327 Next_t next = loopconfig->fNext;
2328 const Int_t offset = config->fOffset;
2329
2331 void *iter = loopconfig->fCopyIterator(iterator,start);
2332 void *addr;
2333 while( (addr = next(iter,end)) ) {
2334 T *x = (T*)( ((char*)addr) + offset );
2335 buf >> *x;
2336 }
2337 if (iter != &iterator[0]) {
2338 loopconfig->fDeleteIterator(iter);
2339 }
2340 return 0;
2341 }
2342
2343 template <typename T>
2344 static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2345 {
2346 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2347
2348 Next_t next = loopconfig->fNext;
2349 const Int_t offset = config->fOffset;
2350
2352 void *iter = loopconfig->fCopyIterator(iterator,start);
2353 void *addr;
2354 while( (addr = next(iter,end)) ) {
2355 T *x = (T*)( ((char*)addr) + offset );
2356 buf << *x;
2357 }
2358 if (iter != &iterator[0]) {
2359 loopconfig->fDeleteIterator(iter);
2360 }
2361 return 0;
2362 }
2363
2364 template <Int_t (*iter_action)(TBuffer&,void *,const TConfiguration*)>
2365 static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2366 {
2367 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2368
2369 // const Int_t offset = config->fOffset;
2370 Next_t next = loopconfig->fNext;
2371
2373 void *iter = loopconfig->fCopyIterator(&iterator,start);
2374 void *addr;
2375 while( (addr = next(iter,end)) ) {
2376 iter_action(buf, addr, config);
2377 }
2378 if (iter != &iterator[0]) {
2379 loopconfig->fDeleteIterator(iter);
2380 }
2381 return 0;
2382 }
2383
2384 template <typename From, typename To>
2385 struct Generic {
2386 static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2387 {
2388 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2389
2390 const Int_t offset = config->fOffset;
2391 Next_t next = loopconfig->fNext;
2392
2394 void *iter = loopconfig->fCopyIterator(&iterator,start);
2395 void *addr;
2396 while( (addr = next(iter,end)) ) {
2397 To *x = (To*)( ((char*)addr) + offset );
2398 *x = (To)(*items);
2399 ++items;
2400 }
2401 if (iter != &iterator[0]) {
2402 loopconfig->fDeleteIterator(iter);
2403 }
2404 }
2405 };
2406
2407 template <typename From, typename To>
2408 struct Numeric {
2409 static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration * /* config */)
2410 {
2411 // The difference with ConvertAction is that we can modify the start
2412 // iterator and skip the copy. We also never have an offset.
2413
2414 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2415 Next_t next = loopconfig->fNext;
2416
2417 void *iter = start;
2418 void *addr;
2419 while( (addr = next(iter,end)) ) {
2420 To *x = (To*)(addr);
2421 *x = (To)(*items);
2422 ++items;
2423 }
2424 }
2425 };
2426
2427 template <typename From, typename To, template <typename F, typename T> class Converter = Generic >
2429 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2430 {
2431 // Simple conversion from a 'From' on disk to a 'To' in memory.
2432
2433 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2434 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2435 Int_t nvalues = proxy->Size();
2436
2437 From *items = new From[nvalues];
2438 buf.ReadFastArray(items, nvalues);
2439 Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
2440 delete [] items;
2441 return 0;
2442 }
2443 };
2444
2445 template <typename To>
2447 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2448 {
2449 // Simple conversion from a 'From' on disk to a 'To' in memory.
2450
2451 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2452 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2453 Int_t nvalues = proxy->Size();
2454
2455 UInt_t *items_storage = new UInt_t[nvalues];
2456 UInt_t *items = items_storage;
2457
2458 const Int_t offset = config->fOffset;
2459 Next_t next = loopconfig->fNext;
2460
2462 void *iter = loopconfig->fCopyIterator(&iterator,start);
2463 void *addr;
2464 while( (addr = next(iter,end)) ) {
2465 buf >> (*items);
2466 if (((*items) & kIsReferenced) != 0) {
2467 HandleReferencedTObject(buf, addr, config);
2468 }
2469 To *x = (To*)( ((char*)addr) + offset );
2470 *x = (To)(*items);
2471 ++items;
2472 }
2473 if (iter != &iterator[0]) {
2474 loopconfig->fDeleteIterator(iter);
2475 }
2476
2477 delete [] items_storage;
2478 return 0;
2479 }
2480 };
2481
2482 template <typename From, typename To, template <typename F, typename T> class Converter >
2483 struct ConvertBasicType<WithFactorMarker<From>,To,Converter > {
2484 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2485 {
2486 // Simple conversion from a 'From' on disk to a 'To' in memory.
2487
2488 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2489 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2490 Int_t nvalues = proxy->Size();
2491
2492 TConfSTLWithFactor *conf = (TConfSTLWithFactor *)config;
2493
2494 From *items = new From[nvalues];
2495 buf.ReadFastArrayWithFactor(items, nvalues, conf->fFactor, conf->fXmin);
2496 Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
2497 delete [] items;
2498 return 0;
2499 }
2500 };
2501
2502 template <typename From, typename To, template <typename F, typename T> class Converter >
2503 struct ConvertBasicType<NoFactorMarker<From>,To,Converter > {
2504 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
2505 {
2506 // Simple conversion from a 'From' on disk to a 'To' in memory.
2507
2508 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2509 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2510 Int_t nvalues = proxy->Size();
2511
2512 TConfSTLNoFactor *conf = (TConfSTLNoFactor *)config;
2513
2514 From *items = new From[nvalues];
2515 buf.ReadFastArrayWithNbits(items, nvalues, conf->fNbits);
2516 Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
2517 delete [] items;
2518 return 0;
2519 }
2520 };
2521
2522 static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
2523 {
2524 // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
2525 // punt.
2526
2527 return GenericRead(buf,start,end,loopconfig, config);
2528 }
2529
2530 static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *, const void *, const TLoopConfiguration * loopconf, const TConfiguration *config)
2531 {
2532 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2533 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2534 return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, *proxy, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ proxy->Size(), config->fOffset, 1|2 );
2535 }
2536
2537 static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *, const void *, const TLoopConfiguration * loopconf, const TConfiguration *config)
2538 {
2539 TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
2540 TVirtualCollectionProxy *proxy = loopconfig->fProxy;
2541 return ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, *proxy, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, proxy->Size(), config->fOffset, 1|2 );
2542 }
2543
2544 template <typename T>
2545 static INLINE_TEMPLATE_ARGS void SimpleRead(TBuffer &buf, void *addr)
2546 {
2547 buf >> *(T*)addr;
2548 }
2549
2550 static INLINE_TEMPLATE_ARGS void SimpleReadFloat16(TBuffer &buf, void *addr)
2551 {
2552 buf.ReadWithNbits((float*)addr,12);
2553 }
2554
2556 {
2557 //we read a float and convert it to double
2558 Float_t afloat;
2559 buf >> afloat;
2560 *(double*)addr = (Double_t)afloat;
2561 }
2562
2563 template <typename ActionHolder>
2565 {
2566 // Collection of numbers. Memberwise or not, it is all the same.
2567
2568 TConfigSTL *config = (TConfigSTL*)conf;
2569 UInt_t start, count;
2570 /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
2571
2572 TClass *newClass = config->fNewClass;
2573 TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
2574 TVirtualCollectionProxy::TPushPop helper( newProxy, ((char*)addr)+config->fOffset );
2575
2576 Int_t nvalues;
2577 buf.ReadInt(nvalues);
2578 void* alternative = newProxy->Allocate(nvalues,true);
2579 if (nvalues) {
2582 void *begin = &(startbuf[0]);
2583 void *end = &(endbuf[0]);
2584 config->fCreateIterators(alternative, &begin, &end, newProxy);
2585 // We can not get here with a split vector of pointer, so we can indeed assume
2586 // that actions->fConfiguration != null.
2587
2588 TGenericLoopConfig loopconf(newProxy, /* read */ kTRUE);
2589 ActionHolder::Action(buf,begin,end,&loopconf,config);
2590
2591 if (begin != &(startbuf[0])) {
2592 // assert(end != endbuf);
2593 config->fDeleteTwoIterators(begin,end);
2594 }
2595 }
2596 newProxy->Commit(alternative);
2597
2598 buf.CheckByteCount(start,count,config->fTypeName);
2599 return 0;
2600 }
2601
2603 {
2604 return ReadNumericalCollection<ConvertBasicType<NoFactorMarker<float>,float,Numeric > >(buf,addr,conf);
2605 }
2606
2608 {
2609 return ReadNumericalCollection<ConvertBasicType<float,double,Numeric > >(buf,addr,conf);
2610 // Could also use:
2611 // return ReadNumericalCollection<ConvertBasicType<NoFactorMarker<double>,double,Numeric > >(buf,addr,conf);
2612 }
2613
2614 template <typename T>
2616 {
2617 //TODO: Check whether we can implement this without loading the data in
2618 // a temporary variable and whether this is noticeably faster.
2619 return ReadNumericalCollection<ConvertBasicType<T,T,Numeric > >(buf,addr,conf);
2620 }
2621
2622 template <typename From, typename To>
2624 static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
2625 {
2626 // return ReadNumericalCollection<To,ConvertRead<From,To>::Action >(buf,addr,conf);
2627 return ReadNumericalCollection<ConvertBasicType<From,To,Numeric > >(buf,addr,conf);
2628 }
2629 };
2630
2631 };
2632}
2633
2634// Used in GetCollectionReadAction for the kConv cases within a collection
2635// Not to be confused with GetConvertCollectionReadAction
2636template <typename Looper, typename From>
2638{
2639 switch (newtype) {
2640 case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertBasicType<From,bool>::Action, conf ); break;
2641 case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ConvertBasicType<From,char>::Action, conf ); break;
2642 case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ConvertBasicType<From,short>::Action, conf ); break;
2643 case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ConvertBasicType<From,Int_t>::Action, conf ); break;
2644 case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ConvertBasicType<From,Long_t>::Action, conf ); break;
2645 case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ConvertBasicType<From,Long64_t>::Action, conf ); break;
2646 case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ConvertBasicType<From,float>::Action, conf ); break;
2647 case TStreamerInfo::kFloat16: return TConfiguredAction( Looper::template ConvertBasicType<From,float>::Action, conf ); break;
2648 case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ConvertBasicType<From,double>::Action, conf ); break;
2649 case TStreamerInfo::kDouble32:return TConfiguredAction( Looper::template ConvertBasicType<From,double>::Action, conf ); break;
2650 case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ConvertBasicType<From,UChar_t>::Action, conf ); break;
2651 case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ConvertBasicType<From,UShort_t>::Action, conf ); break;
2652 case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ConvertBasicType<From,UInt_t>::Action, conf ); break;
2653 case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ConvertBasicType<From,ULong_t>::Action, conf ); break;
2654 case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ConvertBasicType<From,ULong64_t>::Action, conf ); break;
2655 case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ConvertBasicType<From,UInt_t>::Action, conf ); break;
2656 default:
2657 return TConfiguredAction( Looper::GenericRead, conf );
2658 break;
2659 }
2660 R__ASSERT(0); // We should never be here
2661 return TConfiguredAction();
2662}
2663
2664template <class Looper>
2666{
2667 // If we ever support std::vector<Double32_t> fValues; //[...] we would get the info from the StreamerElement for fValues.
2668
2669 switch (type) {
2670 // Read basic types.
2671
2672 // Because of std::vector of bool is not backed up by an array of bool we have to converted it first.
2673 case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertCollectionBasicType<bool,bool>::Action, conf ); break;
2674 case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<Char_t>, conf ); break;
2675 case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<Short_t>,conf ); break;
2676 case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<Int_t>, conf ); break;
2677 case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long_t>, conf ); break;
2678 case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long64_t>, conf ); break;
2679 case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadCollectionBasicType<Float_t>, conf ); break;
2680 case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadCollectionBasicType<Double_t>, conf ); break;
2681 case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<UChar_t>, conf ); break;
2682 case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<UShort_t>, conf ); break;
2683 case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<UInt_t>, conf ); break;
2684 case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong_t>, conf ); break;
2685 case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong64_t>, conf ); break;
2686 case TStreamerInfo::kBits: Error("GetNumericCollectionReadAction","There is no support for kBits outside of a TObject."); break;
2688 TConfigSTL *alternate = new TConfSTLNoFactor(conf,12);
2689 delete conf;
2690 return TConfiguredAction( Looper::ReadCollectionFloat16, alternate );
2691 // if (element->GetFactor() != 0) {
2692 // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2693 // } else {
2694 // Int_t nbits = (Int_t)element->GetXmin();
2695 // if (!nbits) nbits = 12;
2696 // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2697 // }
2698 break;
2699 }
2701 TConfigSTL *alternate = new TConfSTLNoFactor(conf,0);
2702 delete conf;
2703 return TConfiguredAction( Looper::ReadCollectionDouble32, alternate );
2704 // if (element->GetFactor() != 0) {
2705 // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2706 // } else {
2707 // Int_t nbits = (Int_t)element->GetXmin();
2708 // if (!nbits) {
2709 // return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
2710 // } else {
2711 // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2712 // }
2713 // }
2714 break;
2715 }
2716 }
2717 Fatal("GetNumericCollectionReadAction","Is confused about %d",type);
2718 R__ASSERT(0); // We should never be here
2719 return TConfiguredAction();
2720}
2721
2722template <typename Looper, typename From>
2724{
2725 switch (newtype) {
2726 case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,bool>::Action, conf ); break;
2727 case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,char>::Action, conf ); break;
2728 case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,short>::Action, conf ); break;
2729 case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Int_t>::Action, conf ); break;
2730 case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long_t>::Action, conf ); break;
2731 case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long64_t>::Action, conf ); break;
2732 case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2733 case TStreamerInfo::kFloat16: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2734 case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2735 case TStreamerInfo::kDouble32:return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2736 case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UChar_t>::Action, conf ); break;
2737 case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UShort_t>::Action, conf ); break;
2738 case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2739 case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong_t>::Action, conf ); break;
2740 case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong64_t>::Action, conf ); break;
2741 case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2742 default:
2743 break;
2744 }
2745 Error("GetConvertCollectionReadActionFrom", "UNEXPECTED: newtype == %d", newtype);
2746 R__ASSERT(0); // We should never be here
2747 return TConfiguredAction();
2748}
2749
2750// Used in AddReadAction to implement the kSTL cases
2751// Not to be confused with GetCollectionReadConvertAction
2752// nor with GetConvertCollectionReadActionFrom (used to implement this function)
2753template <typename Looper>
2755{
2756 switch (oldtype) {
2758 return GetConvertCollectionReadActionFrom<Looper,Bool_t>(newtype, conf );
2759 break;
2761 return GetConvertCollectionReadActionFrom<Looper,Char_t>(newtype, conf );
2762 break;
2764 return GetConvertCollectionReadActionFrom<Looper,Short_t>(newtype, conf );
2765 break;
2767 return GetConvertCollectionReadActionFrom<Looper,Int_t>(newtype, conf );
2768 break;
2770 return GetConvertCollectionReadActionFrom<Looper,Long_t>(newtype, conf );
2771 break;
2773 return GetConvertCollectionReadActionFrom<Looper,Long64_t>(newtype, conf );
2774 break;
2776 return GetConvertCollectionReadActionFrom<Looper,Float_t>( newtype, conf );
2777 break;
2779 return GetConvertCollectionReadActionFrom<Looper,Double_t>(newtype, conf );
2780 break;
2782 return GetConvertCollectionReadActionFrom<Looper,UChar_t>(newtype, conf );
2783 break;
2785 return GetConvertCollectionReadActionFrom<Looper,UShort_t>(newtype, conf );
2786 break;
2788 return GetConvertCollectionReadActionFrom<Looper,UInt_t>(newtype, conf );
2789 break;
2791 return GetConvertCollectionReadActionFrom<Looper,ULong_t>(newtype, conf );
2792 break;
2794 return GetConvertCollectionReadActionFrom<Looper,ULong64_t>(newtype, conf );
2795 break;
2797 return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Float16_t> >( newtype, conf );
2798 break;
2800 return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Double32_t> >( newtype, conf );
2801 break;
2803 Error("GetConvertCollectionReadAction","There is no support for kBits outside of a TObject.");
2804 break;
2805 default:
2806 break;
2807 }
2808 Error("GetConvertCollectionReadAction", "UNEXPECTED: oldtype == %d", oldtype);
2809 R__ASSERT(0); // We should never be here
2810 return TConfiguredAction();
2811}
2812
2813template <class Looper>
2815{
2816 switch (type) {
2817 // Read basic types.
2818 case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ReadBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2819 case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2820 case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadBasicType<Short_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2821 case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2822 case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2823 case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2824 case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2825 case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2826 case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2827 case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2828 case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2829 case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2830 case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadBasicType<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2831 case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ReadAction<TStreamerInfoActions::ReadBasicType<BitsMarker> > , new TBitsConfiguration(info,i,compinfo,offset) ); break;
2833 if (element->GetFactor() != 0) {
2834 return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2835 } else {
2836 Int_t nbits = (Int_t)element->GetXmin();
2837 if (!nbits) nbits = 12;
2838 return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2839 }
2840 break;
2841 }
2843 if (element->GetFactor() != 0) {
2844 return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2845 } else {
2846 Int_t nbits = (Int_t)element->GetXmin();
2847 if (!nbits) {
2848 return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double>::Action >, new TConfiguration(info,i,compinfo,offset) );
2849 } else {
2850 return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2851 }
2852 }
2853 break;
2854 }
2855 case TStreamerInfo::kTNamed: return TConfiguredAction( Looper::template ReadAction<ReadTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
2856 // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2857 // Streamer alltogether.
2858 case TStreamerInfo::kTObject: return TConfiguredAction( Looper::template ReadAction<ReadTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
2859 case TStreamerInfo::kTString: return TConfiguredAction( Looper::template ReadAction<ReadTString >, new TConfiguration(info,i,compinfo,offset) ); break;
2863 case TStreamerInfo::kSTL: return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) ); break;
2864 case TStreamerInfo::kBase: return TConfiguredAction( Looper::ReadBase, new TGenericConfiguration(info,i,compinfo) ); break;
2865
2866 // Conversions.
2868 return GetCollectionReadConvertAction<Looper,Bool_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2869 break;
2871 return GetCollectionReadConvertAction<Looper,Char_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2872 break;
2874 return GetCollectionReadConvertAction<Looper,Short_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2875 break;
2877 return GetCollectionReadConvertAction<Looper,Int_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2878 break;
2880 return GetCollectionReadConvertAction<Looper,Long_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2881 break;
2883 return GetCollectionReadConvertAction<Looper,Long64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2884 break;
2886 return GetCollectionReadConvertAction<Looper,Float_t>( element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2887 break;
2889 return GetCollectionReadConvertAction<Looper,Double_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2890 break;
2892 return GetCollectionReadConvertAction<Looper,UChar_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2893 break;
2895 return GetCollectionReadConvertAction<Looper,UShort_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2896 break;
2898 return GetCollectionReadConvertAction<Looper,UInt_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2899 break;
2901 return GetCollectionReadConvertAction<Looper,ULong_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2902 break;
2904 return GetCollectionReadConvertAction<Looper,ULong64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2905 break;
2907 return GetCollectionReadConvertAction<Looper,BitsMarker>(element->GetNewType(), new TBitsConfiguration(info,i,compinfo,offset) );
2908 break;
2910 if (element->GetFactor() != 0) {
2911 return GetCollectionReadConvertAction<Looper,WithFactorMarker<float> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2912 } else {
2913 Int_t nbits = (Int_t)element->GetXmin();
2914 if (!nbits) nbits = 12;
2915 return GetCollectionReadConvertAction<Looper,NoFactorMarker<float> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2916 }
2917 break;
2918 }
2920 if (element->GetFactor() != 0) {
2921 return GetCollectionReadConvertAction<Looper,WithFactorMarker<double> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2922 } else {
2923 Int_t nbits = (Int_t)element->GetXmin();
2924 if (!nbits) {
2925 return GetCollectionReadConvertAction<Looper,Float_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2926 } else {
2927 return GetCollectionReadConvertAction<Looper,NoFactorMarker<double> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2928 }
2929 }
2930 break;
2931 }
2932 default:
2933 return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) );
2934 break;
2935 }
2936 R__ASSERT(0); // We should never be here
2937 return TConfiguredAction();
2938}
2939
2940template <class Looper>
2942 switch (type) {
2943 // read basic types
2944 case TStreamerInfo::kBool: return TConfiguredAction( Looper::template WriteBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2945 case TStreamerInfo::kChar: return TConfiguredAction( Looper::template WriteBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2946 case TStreamerInfo::kShort: return TConfiguredAction( Looper::template WriteBasicType<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2947 case TStreamerInfo::kInt: return TConfiguredAction( Looper::template WriteBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2948 case TStreamerInfo::kLong: return TConfiguredAction( Looper::template WriteBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2949 case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template WriteBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2950 case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template WriteBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2951 case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template WriteBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2952 case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template WriteBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2953 case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template WriteBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2954 case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template WriteBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2955 case TStreamerInfo::kULong: return TConfiguredAction( Looper::template WriteBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2956 case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template WriteBasicType<ULong64_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2957 // the simple type missing are kBits and kCounter.
2958 default:
2959 return TConfiguredAction( Looper::GenericWrite, new TConfiguration(info,i,compinfo,0 /* 0 because we call the legacy code */) );
2960 }
2961 R__ASSERT(0); // We should never be here
2962 return TConfiguredAction();
2963}
2964
2965
2966////////////////////////////////////////////////////////////////////////////////
2967/// loop on the TStreamerElement list
2968/// regroup members with same type
2969/// Store predigested information into local arrays. This saves a huge amount
2970/// of time compared to an explicit iteration on all elements.
2971
2973{
2974 if (IsCompiled()) {
2975 //Error("Compile","can only be called once; this first call generates both the optimized and memberwise actions.");
2976 return;
2977 }
2979
2980 // fprintf(stderr,"Running Compile for %s %d %d req=%d,%d\n",GetName(),fClassVersion,fOptimized,CanOptimize(),TestBit(kCannotOptimize));
2981
2982 // if (IsCompiled() && (!fOptimized || (CanOptimize() && !TestBit(kCannotOptimize)))) return;
2984 fNdata = 0;
2985 fNfulldata = 0;
2986
2987 TObjArray* infos = (TObjArray*) gROOT->GetListOfStreamerInfo();
2988 if (fNumber < 0) {
2989 ++fgCount;
2990 fNumber = fgCount;
2991 }
2992 if (fNumber >= infos->GetSize()) {
2993 infos->AddAtAndExpand(this, fNumber);
2994 } else {
2995 if (!infos->At(fNumber)) {
2996 infos->AddAt(this, fNumber);
2997 }
2998 }
2999
3000 assert(fComp == 0 && fCompFull == 0 && fCompOpt == 0);
3001
3002
3003 Int_t ndata = fElements->GetEntriesFast();
3004
3005
3008
3011
3014
3015 if (fReadText) fReadText->fActions.clear();
3016 else fReadText = new TStreamerInfoActions::TActionSequence(this,ndata);
3017
3020
3023
3026
3027 if (fWriteText) fWriteText->fActions.clear();
3029
3030 if (!ndata) {
3031 // This may be the case for empty classes (e.g., TAtt3D).
3032 // We still need to properly set the size of emulated classes (i.e. add the virtual table)
3034 fSize = sizeof(TStreamerInfo*);
3035 }
3036 fComp = new TCompInfo[1];
3037 fCompFull = new TCompInfo*[1];
3038 fCompOpt = new TCompInfo*[1];
3039 fCompOpt[0] = fCompFull[0] = &(fComp[0]);
3040 SetIsCompiled();
3041 return;
3042 }
3043
3044 // At most half of the elements can be used to hold optimized versions.
3045 // We use the bottom to hold the optimized-into elements and the non-optimized elements
3046 // and the top to hold the original copy of the optimized out elements.
3047 fNslots = ndata + ndata/2 + 1;
3048 Int_t optiOut = 0;
3049
3050 fComp = new TCompInfo[fNslots];
3051 fCompFull = new TCompInfo*[ndata];
3052 fCompOpt = new TCompInfo*[ndata];
3053
3054 TStreamerElement* element;
3055 TStreamerElement* previous = 0;
3056 Int_t keep = -1;
3057 Int_t i;
3058
3059 if (!CanOptimize()) {
3061 }
3062
3063 Bool_t isOptimized = kFALSE;
3064 Bool_t previousOptimized = kFALSE;
3065
3066 for (i = 0; i < ndata; ++i) {
3067 element = (TStreamerElement*) fElements->At(i);
3068 if (!element) {
3069 break;
3070 }
3071
3072 Int_t asize = element->GetSize();
3073 if (element->GetArrayLength()) {
3074 asize /= element->GetArrayLength();
3075 }
3076 fComp[fNdata].fType = element->GetType();
3077 fComp[fNdata].fNewType = element->GetNewType();
3078 fComp[fNdata].fOffset = element->GetOffset();
3079 fComp[fNdata].fLength = element->GetArrayLength();
3080 fComp[fNdata].fElem = element;
3081 fComp[fNdata].fMethod = element->GetMethod();
3082 fComp[fNdata].fClass = element->GetClassPointer();
3083 fComp[fNdata].fNewClass = element->GetNewClass();
3085 fComp[fNdata].fStreamer = element->GetStreamer();
3086
3087 // try to group consecutive members of the same type
3089 && (keep >= 0)
3090 && (element->GetType() > 0)
3091 && (element->GetType() < 10)
3093 && (fComp[keep].fMethod == 0)
3094 && (element->GetArrayDim() == 0)
3095 && (fComp[keep].fType < kObject)
3096 && (fComp[keep].fType != kCharStar) /* do not optimize char* */
3097 && (element->GetType() == (fComp[keep].fType%kRegrouped))
3098 && ((element->GetOffset()-fComp[keep].fOffset) == (fComp[keep].fLength)*asize)
3099 && ((fOldVersion<6) || !previous || /* In version of TStreamerInfo less than 6, the Double32_t were merged even if their annotation (aka factor) were different */
3100 ((element->GetFactor() == previous->GetFactor())
3101 && (element->GetXmin() == previous->GetXmin())
3102 && (element->GetXmax() == previous->GetXmax())
3103 )
3104 )
3107 // kWholeObject and kDoNotDelete do not apply to numerical elements.
3108 )
3109 {
3110 if (!previousOptimized) {
3111 // The element was not yet optimized we first need to copy it into
3112 // the set of original copies.
3113 fComp[fNslots - (++optiOut) ] = fComp[keep]; // Copy the optimized out elements.
3114 fCompFull[fNfulldata-1] = &(fComp[fNslots - optiOut]); // Reset the pointer in the full list.
3115 }
3116 fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the optimized out elements.
3117 fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
3118
3119 R__ASSERT( keep < (fNslots - optiOut) );
3120
3121 if (fComp[keep].fLength == 0) {
3122 fComp[keep].fLength++;
3123 }
3124 fComp[keep].fLength++;
3125 fComp[keep].fType = element->GetType() + kRegrouped;
3126 isOptimized = kTRUE;
3127 previousOptimized = kTRUE;
3128 } else if (element->GetType() < 0) {
3129
3130 // -- Deal with an ignored TObject base class.
3131 // Note: The only allowed negative value here is -1,
3132 // and signifies that Build() has found a TObject
3133 // base class and TClass::IgnoreTObjectStreamer() was
3134 // called. In this case the compiled version of the
3135 // elements omits the TObject base class element,
3136 // which has to be compensated for by TTree::Bronch()
3137 // when it is making branches for a split object.
3138 fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the 'ignored' element.
3139 fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
3140 keep = -1;
3141 previousOptimized = kFALSE;
3142
3143 } else {
3144 if (fComp[fNdata].fNewType != fComp[fNdata].fType) {
3145 if (fComp[fNdata].fNewType > 0) {
3146 if ( (fComp[fNdata].fNewType == kObjectp || fComp[fNdata].fNewType == kAnyp
3147 || fComp[fNdata].fNewType == kObject || fComp[fNdata].fNewType == kAny
3148 || fComp[fNdata].fNewType == kTObject || fComp[fNdata].fNewType == kTNamed || fComp[fNdata].fNewType == kTString)
3152 ) {
3154 } else if (fComp[fNdata].fType != kCounter) {
3155 fComp[fNdata].fType += kConv;
3156 }
3157 } else {
3158 if (fComp[fNdata].fType == kCounter) {
3159 Warning("Compile", "Counter %s should not be skipped from class %s", element->GetName(), GetName());
3160 }
3161 fComp[fNdata].fType += kSkip;
3162 }
3163 }
3164 fCompOpt[fNdata] = &(fComp[fNdata]);
3166
3167 R__ASSERT( fNdata < (fNslots - optiOut) );
3168
3169 keep = fNdata;
3170 if (fComp[keep].fLength == 0) {
3171 fComp[keep].fLength = 1;
3172 }
3173 fNdata++;
3174 previousOptimized = kFALSE;
3175 }
3176 // The test 'fMethod[keep] == 0' fails to detect a variable size array
3177 // if the counter happens to have an offset of zero, so let's explicitly
3178 // prevent for here.
3179 if (element->HasCounter()) keep = -1;
3180 ++fNfulldata;
3181 previous = element;
3182 }
3183
3184 for (i = 0; i < fNdata; ++i) {
3185 if (!fCompOpt[i]->fElem || fCompOpt[i]->fElem->GetType()< 0) {
3186 continue;
3187 }
3190 }
3191 for (i = 0; i < fNfulldata; ++i) {
3192 if (!fCompFull[i]->fElem || fCompFull[i]->fElem->GetType()< 0) {
3193 continue;
3194 }
3199
3202 }
3203 ComputeSize();
3204
3205 fOptimized = isOptimized;
3206 SetIsCompiled();
3207
3208 if (gDebug > 0) {
3209 ls();
3210 }
3211}
3212
3213template <typename From>
3215{
3216 switch (newtype) {
3233 }
3234}
3235
3236////////////////////////////////////////////////////////////////////////////////
3237/// Add a read action for the given element.
3238
3240{
3241 TStreamerElement *element = compinfo->fElem;
3242
3243 if (element->TestBit(TStreamerElement::kWrite)) return;
3244
3245 switch (compinfo->fType) {
3246 // read basic types
3247 case TStreamerInfo::kBool: readSequence->AddAction( ReadBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3248 case TStreamerInfo::kChar: readSequence->AddAction( ReadBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3249 case TStreamerInfo::kShort: readSequence->AddAction( ReadBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3250 case TStreamerInfo::kInt: readSequence->AddAction( ReadBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3251 case TStreamerInfo::kLong: readSequence->AddAction( ReadBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3252 case TStreamerInfo::kLong64: readSequence->AddAction( ReadBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3253 case TStreamerInfo::kFloat: readSequence->AddAction( ReadBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3254 case TStreamerInfo::kDouble: readSequence->AddAction( ReadBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3255 case TStreamerInfo::kUChar: readSequence->AddAction( ReadBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3256 case TStreamerInfo::kUShort: readSequence->AddAction( ReadBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3257 case TStreamerInfo::kUInt: readSequence->AddAction( ReadBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3258 case TStreamerInfo::kULong: readSequence->AddAction( ReadBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3259 case TStreamerInfo::kULong64: readSequence->AddAction( ReadBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3260 case TStreamerInfo::kBits: readSequence->AddAction( ReadBasicType<BitsMarker>, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3262 if (element->GetFactor() != 0) {
3263 readSequence->AddAction( ReadBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3264 } else {
3265 Int_t nbits = (Int_t)element->GetXmin();
3266 if (!nbits) nbits = 12;
3267 readSequence->AddAction( ReadBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3268 }
3269 break;
3270 }
3272 if (element->GetFactor() != 0) {
3273 readSequence->AddAction( ReadBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3274 } else {
3275 Int_t nbits = (Int_t)element->GetXmin();
3276 if (!nbits) {
3277 readSequence->AddAction( ConvertBasicType<float,double>::Action, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3278 } else {
3279 readSequence->AddAction( ReadBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3280 }
3281 }
3282 break;
3283 }
3284 case TStreamerInfo::kTNamed: readSequence->AddAction( ReadTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3285 // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
3286 // Streamer alltogether.
3287 case TStreamerInfo::kTObject: readSequence->AddAction( ReadTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3288 case TStreamerInfo::kTString: readSequence->AddAction( ReadTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3289 case TStreamerInfo::kSTL: {
3290 TClass *newClass = element->GetNewClass();
3291 TClass *oldClass = element->GetClassPointer();
3292 Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
3293
3294 if (element->GetArrayLength() <= 1) {
3295 if (fOldVersion<3){ // case of old TStreamerInfo
3296 if (newClass && newClass != oldClass) {
3297 if (element->GetStreamer()) {
3298 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3299 } else {
3300 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
3301 }
3302 } else {
3303 if (element->GetStreamer()) {
3304 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3305 } else {
3306 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
3307 }
3308 }
3309 } else {
3310 if (newClass && newClass != oldClass) {
3311 if (element->GetStreamer()) {
3312 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3313 } else if (oldClass) {
3314 if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
3315 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
3316 } else {
3317 switch (SelectLooper(*newClass->GetCollectionProxy())) {
3318 case kVectorLooper:
3319 readSequence->AddAction(GetConvertCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
3320 break;
3321 case kAssociativeLooper:
3322 readSequence->AddAction(GetConvertCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
3323 break;
3324 case kVectorPtrLooper:
3325 case kGenericLooper:
3326 default:
3327 // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
3328 readSequence->AddAction(GetConvertCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
3329 break;
3330 }
3331 }
3332 }
3333 } else {
3334 if (element->GetStreamer()) {
3335 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3336 } else if (oldClass) {
3337 if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
3338 readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
3339 } else {
3340 switch (SelectLooper(*oldClass->GetCollectionProxy())) {
3341 case kVectorLooper:
3342 readSequence->AddAction(GetNumericCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
3343 break;
3344 case kAssociativeLooper:
3345 readSequence->AddAction(GetNumericCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
3346 break;
3347 case kVectorPtrLooper:
3348 case kGenericLooper:
3349 default:
3350 // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
3351 readSequence->AddAction(GetNumericCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
3352 break;
3353 }
3354 }
3355 }
3356 }
3357 }
3358 } else {
3359 if (fOldVersion<3){ // case of old TStreamerInfo
3360 if (newClass && newClass != oldClass) {
3361 if (element->GetStreamer()) {
3362 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3363 } else {
3364 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
3365 }
3366 } else {
3367 if (element->GetStreamer()) {
3368 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3369 } else {
3370 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
3371 }
3372 }
3373 } else {
3374 if (newClass && newClass != oldClass) {
3375 if (element->GetStreamer()) {
3376 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3377 } else {
3378 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
3379 }
3380 } else {
3381 if (element->GetStreamer()) {
3382 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3383 } else {
3384 readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
3385 }
3386 }
3387 }
3388 }
3389 break;
3390 }
3391
3393 AddReadConvertAction<Bool_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3394 break;
3396 AddReadConvertAction<Char_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3397 break;
3399 AddReadConvertAction<Short_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3400 break;
3402 AddReadConvertAction<Int_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3403 break;
3405 AddReadConvertAction<Long_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3406 break;
3408 AddReadConvertAction<Long64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3409 break;
3411 AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3412 break;
3414 AddReadConvertAction<Double_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3415 break;
3417 AddReadConvertAction<UChar_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3418 break;
3420 AddReadConvertAction<UShort_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3421 break;
3423 AddReadConvertAction<UInt_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3424 break;
3426 AddReadConvertAction<ULong_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3427 break;
3429 AddReadConvertAction<ULong64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3430 break;
3432 AddReadConvertAction<BitsMarker>(readSequence, compinfo->fNewType, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) );
3433 break;
3435 if (element->GetFactor() != 0) {
3436 AddReadConvertAction<WithFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3437 } else {
3438 Int_t nbits = (Int_t)element->GetXmin();
3439 if (!nbits) nbits = 12;
3440 AddReadConvertAction<NoFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3441 }
3442 break;
3443 }
3445 if (element->GetFactor() != 0) {
3446 AddReadConvertAction<WithFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3447 } else {
3448 Int_t nbits = (Int_t)element->GetXmin();
3449 if (!nbits) {
3450 AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3451 } else {
3452 AddReadConvertAction<NoFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3453 }
3454 }
3455 break;
3456 }
3457 default:
3458 readSequence->AddAction( GenericReadAction, new TGenericConfiguration(this,i,compinfo) );
3459 break;
3460 }
3461 if (element->TestBit(TStreamerElement::kCache)) {
3462 TConfiguredAction action( readSequence->fActions.back() ); // Action is moved, we must pop it next.
3463 readSequence->fActions.pop_back();
3464 readSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
3465 }
3466}
3467
3468////////////////////////////////////////////////////////////////////////////////
3469/// Add a read text action for the given element.
3470
3472{
3473 TStreamerElement *element = compinfo->fElem;
3474
3475 if (element->TestBit(TStreamerElement::kWrite))
3476 return;
3477
3478 Bool_t generic = kFALSE, isBase = kFALSE;
3479
3480 switch (compinfo->fType) {
3482 if (element->IsBase())
3483 isBase = kTRUE;
3484 // readSequence->AddAction( ReadTextTObjectBase, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3485 else
3486 readSequence->AddAction(ReadTextTObject, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3487 break;
3488
3490 if (element->IsBase())
3491 isBase = kTRUE;
3492 // generic = kTRUE; // for the base class one cannot call TClass::Streamer() as performed for the normal object
3493 else
3494 readSequence->AddAction(ReadTextTNamed, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3495 break;
3496
3497 case TStreamerInfo::kObject: // Class derived from TObject
3498 case TStreamerInfo::kAny: // Class NOT derived from TObject
3501 readSequence->AddAction(ReadTextObject, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3502 break;
3503
3504 case TStreamerInfo::kSTLp: // Pointer to container with no virtual table (stl) and no comment
3506 TStreamerInfo::kOffsetL: // array of pointers to container with no virtual table (stl) and no comment
3507 readSequence->AddAction(ReadSTLp<true>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3508 break;
3509
3512 readSequence->AddAction(ReadStreamerLoop<true>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3513 break;
3514
3515 case TStreamerInfo::kBase: isBase = kTRUE; break;
3516
3518 readSequence->AddAction(ReadTextStreamer, new TGenericConfiguration(this, i, compinfo));
3519 break;
3520
3521 default: generic = kTRUE; break;
3522 }
3523
3524 if (isBase) {
3525 if (compinfo->fStreamer) {
3526 readSequence->AddAction(ReadTextStreamer, new TGenericConfiguration(this, i, compinfo));
3527 } else {
3528 readSequence->AddAction(ReadTextBaseClass, new TGenericConfiguration(this, i, compinfo));
3529 }
3530 } else if (generic)
3531 readSequence->AddAction(GenericReadAction, new TGenericConfiguration(this, i, compinfo));
3532}
3533
3534////////////////////////////////////////////////////////////////////////////////
3535/// Add a read action for the given element.
3536/// This is for streaming via a TClonesArray (or a vector of pointers of this type).
3537
3539{
3540 TStreamerElement *element = compinfo->fElem;
3541
3542 if (element->TestBit(TStreamerElement::kWrite)) return;
3543
3544 if (element->TestBit(TStreamerElement::kCache)) {
3545 TConfiguredAction action( GetCollectionReadAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
3546 readSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
3547 } else {
3548 readSequence->AddAction( GetCollectionReadAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
3549 }
3550}
3551
3552////////////////////////////////////////////////////////////////////////////////
3553
3555{
3556 TStreamerElement *element = compinfo->fElem;
3558 // Skip element cached for reading purposes.
3559 return;
3560 }
3561 if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
3562 // Skip artificial element used for reading purposes.
3563 return;
3564 }
3565 switch (compinfo->fType) {
3566 // write basic types
3567 case TStreamerInfo::kBool: writeSequence->AddAction( WriteBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3568 case TStreamerInfo::kChar: writeSequence->AddAction( WriteBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3569 case TStreamerInfo::kShort: writeSequence->AddAction( WriteBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3570 case TStreamerInfo::kInt: writeSequence->AddAction( WriteBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3571 case TStreamerInfo::kLong: writeSequence->AddAction( WriteBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3572 case TStreamerInfo::kLong64: writeSequence->AddAction( WriteBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3573 case TStreamerInfo::kFloat: writeSequence->AddAction( WriteBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3574 case TStreamerInfo::kDouble: writeSequence->AddAction( WriteBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3575 case TStreamerInfo::kUChar: writeSequence->AddAction( WriteBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3576 case TStreamerInfo::kUShort: writeSequence->AddAction( WriteBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3577 case TStreamerInfo::kUInt: writeSequence->AddAction( WriteBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3578 case TStreamerInfo::kULong: writeSequence->AddAction( WriteBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3579 case TStreamerInfo::kULong64: writeSequence->AddAction( WriteBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3580 // case TStreamerInfo::kBits: writeSequence->AddAction( WriteBasicType<BitsMarker>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3581 /*case TStreamerInfo::kFloat16: {
3582 if (element->GetFactor() != 0) {
3583 writeSequence->AddAction( WriteBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3584 } else {
3585 Int_t nbits = (Int_t)element->GetXmin();
3586 if (!nbits) nbits = 12;
3587 writeSequence->AddAction( WriteBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3588 }
3589 break;
3590 } */
3591 /*case TStreamerInfo::kDouble32: {
3592 if (element->GetFactor() != 0) {
3593 writeSequence->AddAction( WriteBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3594 } else {
3595 Int_t nbits = (Int_t)element->GetXmin();
3596 if (!nbits) {
3597 writeSequence->AddAction( ConvertBasicType<float,double>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
3598 } else {
3599 writeSequence->AddAction( WriteBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3600 }
3601 }
3602 break;
3603 } */
3604 //case TStreamerInfo::kTNamed: writeSequence->AddAction( WriteTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3605 // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
3606 // Streamer alltogether.
3607 //case TStreamerInfo::kTObject: writeSequence->AddAction( WriteTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3608 //case TStreamerInfo::kTString: writeSequence->AddAction( WriteTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3609 /*case TStreamerInfo::kSTL: {
3610 TClass *newClass = element->GetNewClass();
3611 TClass *oldClass = element->GetClassPointer();
3612 Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
3613
3614 if (element->GetArrayLength() <= 1) {
3615 if (newClass && newClass != oldClass) {
3616 if (element->GetStreamer()) {
3617 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3618 } else {
3619 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
3620 }
3621 } else {
3622 if (element->GetStreamer()) {
3623 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3624 } else {
3625 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
3626 }
3627 }
3628 } else {
3629 if (newClass && newClass != oldClass) {
3630 if (element->GetStreamer()) {
3631 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3632 } else {
3633 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
3634 }
3635 } else {
3636 if (element->GetStreamer()) {
3637 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3638 } else {
3639 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
3640 }
3641 }
3642 }
3643 break;
3644 } */
3645 default:
3646 writeSequence->AddAction( GenericWriteAction, new TGenericConfiguration(this,i,compinfo) );
3647 break;
3648 }
3649#if defined(CDJ_NO_COMPILE)
3650 if (element->TestBit(TStreamerElement::kCache)) {
3651 TConfiguredAction action( writeSequence->fActions.back() ); // Action is moved, we must pop it next.
3652 writeSequence->fActions.pop_back();
3653 writeSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
3654 }
3655#endif
3656}
3657
3658////////////////////////////////////////////////////////////////////////////////
3659
3661{
3662 TStreamerElement *element = compinfo->fElem;
3664 // Skip element cached for reading purposes.
3665 return;
3666 }
3667 if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
3668 // Skip artificial element used for reading purposes.
3669 return;
3670 }
3671
3672 Bool_t generic = kFALSE, isBase = kFALSE;
3673
3674 switch (compinfo->fType) {
3675 // write basic types
3677 writeSequence->AddAction(WriteBasicType<Bool_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3678 break;
3680 writeSequence->AddAction(WriteBasicType<Char_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3681 break;
3683 writeSequence->AddAction(WriteBasicType<Short_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3684 break;
3686 writeSequence->AddAction(WriteBasicType<Int_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3687 break;
3689 writeSequence->AddAction(WriteBasicType<Long_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3690 break;
3692 writeSequence->AddAction(WriteBasicType<Long64_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3693 break;
3695 writeSequence->AddAction(WriteBasicType<Float_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3696 break;
3698 writeSequence->AddAction(WriteBasicType<Double_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3699 break;
3701 writeSequence->AddAction(WriteBasicType<UChar_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3702 break;
3704 writeSequence->AddAction(WriteBasicType<UShort_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3705 break;
3707 writeSequence->AddAction(WriteBasicType<UInt_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3708 break;
3710 writeSequence->AddAction(WriteBasicType<ULong_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3711 break;
3713 writeSequence->AddAction(WriteBasicType<ULong64_t>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3714 break;
3715
3717 if (element->IsBase())
3718 isBase = kTRUE;
3719 else
3720 writeSequence->AddAction(WriteTextTObject, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3721 break;
3722
3724 if (element->IsBase())
3725 isBase = kTRUE;
3726 else
3727 writeSequence->AddAction(WriteTextTNamed, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3728 break;
3729
3730 case TStreamerInfo::kSTLp: // Pointer to container with no virtual table (stl) and no comment
3732 TStreamerInfo::kOffsetL: // array of pointers to container with no virtual table (stl) and no comment
3733 writeSequence->AddAction(WriteSTLp<true>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3734 break;
3735
3738 writeSequence->AddAction(WriteStreamerLoop<true>, new TConfiguration(this, i, compinfo, compinfo->fOffset));
3739 break;
3740
3741 case TStreamerInfo::kBase: isBase = kTRUE; break;
3742
3744 writeSequence->AddAction(WriteTextStreamer, new TGenericConfiguration(this, i, compinfo));
3745 break;
3746
3747 // case TStreamerInfo::kBits: writeSequence->AddAction( WriteBasicType<BitsMarker>, new
3748 // TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3749 /*case TStreamerInfo::kFloat16: {
3750 if (element->GetFactor() != 0) {
3751 writeSequence->AddAction( WriteBasicType_WithFactor<float>, new
3752 TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3753 } else {
3754 Int_t nbits = (Int_t)element->GetXmin();
3755 if (!nbits) nbits = 12;
3756 writeSequence->AddAction( WriteBasicType_NoFactor<float>, new
3757 TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3758 }
3759 break;
3760 } */
3761 /*case TStreamerInfo::kDouble32: {
3762 if (element->GetFactor() != 0) {
3763 writeSequence->AddAction( WriteBasicType_WithFactor<double>, new
3764 TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
3765 } else {
3766 Int_t nbits = (Int_t)element->GetXmin();
3767 if (!nbits) {
3768 writeSequence->AddAction( ConvertBasicType<float,double>, new
3769 TConfiguration(this,i,compinfo,compinfo->fOffset) );
3770 } else {
3771 writeSequence->AddAction( WriteBasicType_NoFactor<double>, new
3772 TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
3773 }
3774 }
3775 break;
3776 } */
3777 // case TStreamerInfo::kTNamed: writeSequence->AddAction( WriteTNamed, new
3778 // TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3779 // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
3780 // Streamer alltogether.
3781 // case TStreamerInfo::kTObject: writeSequence->AddAction( WriteTObject, new
3782 // TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3783 // case TStreamerInfo::kTString: writeSequence->AddAction( WriteTString, new
3784 // TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
3785 /*case TStreamerInfo::kSTL: {
3786 TClass *newClass = element->GetNewClass();
3787 TClass *oldClass = element->GetClassPointer();
3788 Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
3789
3790 if (element->GetArrayLength() <= 1) {
3791 if (newClass && newClass != oldClass) {
3792 if (element->GetStreamer()) {
3793 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new
3794 TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3795 } else {
3796 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new
3797 TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
3798 }
3799 } else {
3800 if (element->GetStreamer()) {
3801 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new
3802 TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3803 } else {
3804 writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new
3805 TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
3806 }
3807 }
3808 } else {
3809 if (newClass && newClass != oldClass) {
3810 if (element->GetStreamer()) {
3811 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new
3812 TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3813 } else {
3814 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new
3815 TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
3816 }
3817 } else {
3818 if (element->GetStreamer()) {
3819 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new
3820 TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
3821 } else {
3822 writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new
3823 TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
3824 }
3825 }
3826 }
3827 break;
3828 } */
3829 default: generic = kTRUE; break;
3830 }
3831
3832 if (isBase) {
3833 if (compinfo->fStreamer) {
3834 writeSequence->AddAction(WriteTextStreamer, new TGenericConfiguration(this, i, compinfo));
3835 } else {
3836 writeSequence->AddAction(WriteTextBaseClass, new TGenericConfiguration(this, i, compinfo));
3837 }
3838
3839 } else
3840
3841 // use generic write action when special handling is not provided
3842 if (generic)
3843 writeSequence->AddAction(GenericWriteAction, new TGenericConfiguration(this, i, compinfo));
3844
3845#if defined(CDJ_NO_COMPILE)
3846 if (element->TestBit(TStreamerElement::kCache)) {
3847 TConfiguredAction action(writeSequence->fActions.back()); // Action is moved, we must pop it next.
3848 writeSequence->fActions.pop_back();
3849 writeSequence->AddAction(UseCache,
3850 new TConfigurationUseCache(this, action, element->TestBit(TStreamerElement::kRepeat)));
3851 }
3852#endif
3853}
3854
3855////////////////////////////////////////////////////////////////////////////////
3856/// This is for streaming via a TClonesArray (or a vector of pointers of this type).
3857
3859{
3860 TStreamerElement *element = compinfo->fElem;
3862 // Skip element cached for reading purposes.
3863 return;
3864 }
3865 if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
3866 // Skip artificial element used for reading purposes.
3867 return;
3868 }
3869
3870#if defined(CDJ_NO_COMPILE)
3871 if (element->TestBit(TStreamerElement::kCache)) {
3872 TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
3873 writeSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
3874 } else {
3875 writeSequence->Addaction( GetCollectionWriteAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
3876 }
3877#else
3878 writeSequence->AddAction( VectorPtrLooper::GenericWrite, new TGenericConfiguration(this,i,compinfo) );
3879#endif
3880
3881}
3882
3883////////////////////////////////////////////////////////////////////////////////
3884/// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
3885
3887{
3888 if (info == 0) {
3890 }
3891
3892 TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
3893
3894 UInt_t ndata = info->GetElements()->GetEntriesFast();
3896 if (IsDefaultVector(proxy))
3897 {
3898 if (proxy.HasPointers()) {
3899 // Instead of the creating a new one let's copy the one from the StreamerInfo.
3900 delete sequence;
3901
3902 sequence = sinfo->GetReadMemberWiseActions(kTRUE)->CreateCopy();
3903
3904 return sequence;
3905 }
3906
3907 // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3908 Long_t increment = proxy.GetIncrement();
3909 sequence->fLoopConfig = new TVectorLoopConfig(&proxy, increment, /* read */ kTRUE);
3914 {
3915 Long_t increment = proxy.GetIncrement();
3916 sequence->fLoopConfig = new TVectorLoopConfig(&proxy, increment, /* read */ kTRUE);
3917 // sequence->fLoopConfig = new TAssocLoopConfig(proxy);
3918 } else {
3919 sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kTRUE);
3920 }
3921 for (UInt_t i = 0; i < ndata; ++i) {
3922 TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
3923 if (!element) {
3924 break;
3925 }
3926 if (element->GetType() < 0) {
3927 // -- Skip an ignored TObject base class.
3928 // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
3929 // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
3930 // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
3931 // when it is making branches for a split object.
3932 continue;
3933 }
3934 if (element->TestBit(TStreamerElement::kWrite)) {
3935 // Skip element that only for writing.
3936 continue;
3937 }
3938 TStreamerBase *baseEl = dynamic_cast<TStreamerBase*>(element);
3939 if (baseEl) {
3940 if (!baseEl->TestBit(TStreamerElement::kWarned) && baseEl->GetErrorMessage()[0]) {
3941 // There was a problem with the checksum, the user likely did not
3942 // increment the version number of the derived class when the
3943 // base class changed. Since we will be member wise streaming
3944 // this class, let's warn the user that something is wrong.
3945 ::Warning("CreateReadMemberWiseActions","%s",
3946 baseEl->GetErrorMessage());
3948 }
3949 }
3950
3951 TStreamerInfo::TCompInfo_t *compinfo = sinfo->fCompFull[i];
3952
3953 Int_t oldType = element->GetType();
3954 Int_t newType = element->GetNewType();
3955
3956 Int_t offset = element->GetOffset();
3957 if (newType != oldType) {
3958 if (newType > 0) {
3959 if (oldType != TVirtualStreamerInfo::kCounter) {
3960 oldType += TVirtualStreamerInfo::kConv;
3961 }
3962 } else {
3963 oldType += TVirtualStreamerInfo::kSkip;
3964 }
3965 }
3966 switch (SelectLooper(proxy)) {
3967 case kAssociativeLooper:
3968// } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3969// || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
3970// sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
3971 case kVectorLooper:
3972 case kVectorPtrLooper:
3973 // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3974 if (element->TestBit(TStreamerElement::kCache)) {
3975 TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3977 } else {
3978 sequence->AddAction( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
3979 }
3980 break;
3981 case kGenericLooper:
3982 default:
3983 // The usual collection case.
3984 if (element->TestBit(TStreamerElement::kCache)) {
3985 TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3987 } else {
3988 sequence->AddAction( GetCollectionReadAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
3989 }
3990 break;
3991 }
3992 }
3993 return sequence;
3994}
3995
3996////////////////////////////////////////////////////////////////////////////////
3997/// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
3998
4000{
4001 if (info == 0) {
4003 }
4004
4005 UInt_t ndata = info->GetElements()->GetEntriesFast();
4006 TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
4008
4009 if (IsDefaultVector(proxy))
4010 {
4011 if (proxy.HasPointers()) {
4012 // Instead of the creating a new one let's copy the one from the StreamerInfo.
4013 delete sequence;
4014
4015 sequence = sinfo->GetWriteMemberWiseActions(kTRUE)->CreateCopy();
4016
4017 return sequence;
4018 }
4019
4020 // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
4021 Long_t increment = proxy.GetIncrement();
4022 sequence->fLoopConfig = new TVectorLoopConfig(&proxy, increment, /* read */ kFALSE);
4023 /*} else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
4024 || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)
4025 {
4026 Long_t increment = proxy.GetIncrement();
4027 sequence->fLoopConfig = new TVectorLoopConfig(increment);
4028 // sequence->fLoopConfig = new TAssocLoopConfig(proxy); */
4029 } else {
4030 sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kFALSE);
4031 }
4032 for (UInt_t i = 0; i < ndata; ++i) {
4033 TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
4034 if (!element) {
4035 break;
4036 }
4037 if (element->GetType() < 0) {
4038 // -- Skip an ignored TObject base class.
4039 // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
4040 // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
4041 // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
4042 // when it is making branches for a split object.
4043 continue;
4044 }
4046 // Skip element cached for reading purposes.
4047 continue;
4048 }
4050 // Skip artificial element used for reading purposes.
4051 continue;
4052 }
4053 TStreamerInfo::TCompInfo *compinfo = sinfo->fCompFull[i];
4054 Int_t oldType = element->GetType();
4055 Int_t offset = element->GetOffset();
4056#if defined(CDJ_NO_COMPILE)
4057 Int_t newType = element->GetNewType();
4058
4059 if (newType != oldType) {
4060 if (newType > 0) {
4061 if (oldType != TVirtualStreamerInfo::kCounter) {
4062 oldType += TVirtualStreamerInfo::kConv;
4063 }
4064 } else {
4065 oldType += TVirtualStreamerInfo::kSkip;
4066 }
4067 }
4068 if ( IsDefaultVector(proxy)
4069 /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
4070 || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) */ )
4071 {
4072
4073 // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
4074 if (element->TestBit(TStreamerElement::kCache)) {
4075 TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
4077 } else {
4078 sequence->AddAction(GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
4079 }
4080
4081 // } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
4082 // || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
4083 // sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
4084 } else {
4085 // The usual collection case.
4086 if (element->TestBit(TStreamerElement::kCache)) {
4087 TConfiguredAction action( GetWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
4089 } else {
4090 switch (oldType) {
4091 // read basic types
4092 case TVirtualStreamerInfo::kBool: sequence->AddAction( WriteBasicTypeGenericLoop<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4093 case TVirtualStreamerInfo::kChar: sequence->AddAction( WriteBasicTypeGenericLoop<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4094 case TVirtualStreamerInfo::kShort: sequence->AddAction( WriteBasicTypeGenericLoop<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4095 case TVirtualStreamerInfo::kInt: sequence->AddAction( WriteBasicTypeGenericLoop<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4096 case TVirtualStreamerInfo::kLong: sequence->AddAction( WriteBasicTypeGenericLoop<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4097 case TVirtualStreamerInfo::kLong64: sequence->AddAction( WriteBasicTypeGenericLoop<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4098 case TVirtualStreamerInfo::kFloat: sequence->AddAction( WriteBasicTypeGenericLoop<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4099 case TVirtualStreamerInfo::kDouble: sequence->AddAction( WriteBasicTypeGenericLoop<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4100 case TVirtualStreamerInfo::kUChar: sequence->AddAction( WriteBasicTypeGenericLoop<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4101 case TVirtualStreamerInfo::kUShort: sequence->AddAction( WriteBasicTypeGenericLoop<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4102 case TVirtualStreamerInfo::kUInt: sequence->AddAction( WriteBasicTypeGenericLoop<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4103 case TVirtualStreamerInfo::kULong: sequence->AddAction( WriteBasicTypeGenericLoop<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4104 case TVirtualStreamerInfo::kULong64: sequence->AddAction( WriteBasicTypeGenericLoop<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
4105 // case TVirtualStreamerInfo::kBits: sequence->AddAction( WriteBasicTypeGenericLoop<BitsMarker>, new TConfiguration(info,i,compinfo,offset) ); break;
4107 if (element->GetFactor() != 0) {
4108 sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
4109 } else {
4110 Int_t nbits = (Int_t)element->GetXmin();
4111 if (!nbits) nbits = 12;
4112 sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
4113 }
4114 break;
4115 }
4117 if (element->GetFactor() != 0) {
4118 sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
4119 } else {
4120 Int_t nbits = (Int_t)element->GetXmin();
4121 if (!nbits) {
4122 sequence->AddAction( GenericLooper<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
4123 } else {
4124 sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
4125 }
4126 }
4127 break;
4128 }
4129 case TVirtualStreamerInfo::kTNamed: sequence->AddAction( GenericLooper<WriteTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
4130 // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
4131 // Streamer alltogether.
4132 case TVirtualStreamerInfo::kTObject: sequence->AddAction( GenericLooper<WriteTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
4133 case TVirtualStreamerInfo::kTString: sequence->AddAction( GenericLooper<WriteTString >, new TConfiguration(info,i,compinfo,offset) ); break;
4134 default:
4135 sequence->AddAction( GenericCollectionWriteAction, new TConfigSTL(info,i,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
4136 break;
4137 }
4138 }
4139 }
4140#else
4141 if ( IsDefaultVector(proxy)
4142 /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
4143 || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)*/ )
4144 {
4145 sequence->AddAction( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
4146 } else {
4147 // NOTE: TBranch::FillLeavesCollection[Member] is not yet ready to handle the sequence
4148 // as it does not create/use a TStaging as expected ... but then again it might
4149 // not be the right things to expect ...
4150 // sequence->AddAction( GetCollectionWriteAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
4151 sequence->AddAction( GenericLooper::GenericWrite, new TConfigSTL(info,i,compinfo,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
4152 }
4153#endif
4154 }
4155 return sequence;
4156}
4157
4159{
4160 // Add the (potentially negative) delta to all the configuration's offset. This is used by
4161 // TBranchElement in the case of split sub-object.
4162
4163 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4164 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4165 iter != end;
4166 ++iter)
4167 {
4168 // (fElemId == -1) indications that the action is a Push or Pop DataCache.
4169 if (iter->fConfiguration->fElemId != (UInt_t)-1 &&
4170 !iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4171 iter->fConfiguration->AddToOffset(delta);
4172 }
4173}
4174
4176{
4177 // Add the (potentially negative) delta to all the configuration's offset. This is used by
4178 // TBranchElement in the case of split sub-object.
4179
4180 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4181 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4182 iter != end;
4183 ++iter)
4184 {
4185 if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4186 iter->fConfiguration->SetMissing();
4187 }
4188}
4189
4191{
4192 // Create a copy of this sequence.
4193
4194 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo, fActions.size(), IsForVectorPtrLooper());
4195
4196 sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
4197
4198 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4199 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4200 iter != end;
4201 ++iter)
4202 {
4203 TConfiguration *conf = iter->fConfiguration->Copy();
4204 sequence->AddAction( iter->fAction, conf );
4205 }
4206 return sequence;
4207}
4208
4210 const TStreamerInfoActions::TIDs &element_ids,
4211 Int_t offset,
4213{
4214 for(UInt_t id = 0; id < element_ids.size(); ++id) {
4215 if ( element_ids[id].fElemID < 0 ) {
4216 if (element_ids[id].fNestedIDs) {
4217 auto original = create(element_ids[id].fNestedIDs->fInfo,
4218 sequence->fLoopConfig ? sequence->fLoopConfig->GetCollectionProxy() : nullptr,
4219 nullptr);
4220 if (element_ids[id].fNestedIDs->fOnfileObject) {
4221 auto conf = new TConfigurationPushDataCache(element_ids[id].fNestedIDs->fInfo, element_ids[id].fNestedIDs->fOnfileObject, offset);
4222 if ( sequence->fLoopConfig )
4223 sequence->AddAction( PushDataCacheGenericCollection, conf );
4224 else if ( sequence->IsForVectorPtrLooper() )
4225 sequence->AddAction( PushDataCacheVectorPtr, conf );
4226 else
4227 sequence->AddAction( PushDataCache, conf );
4228 }
4229
4230 original->AddToSubSequence(sequence, element_ids[id].fNestedIDs->fIDs, element_ids[id].fNestedIDs->fOffset, create);
4231
4232 if (element_ids[id].fNestedIDs->fOnfileObject) {
4233 auto conf =
4234 new TConfigurationPushDataCache(element_ids[id].fNestedIDs->fInfo, nullptr, element_ids[id].fNestedIDs->fOffset);
4235 if ( sequence->fLoopConfig )
4236 sequence->AddAction( PopDataCacheGenericCollection, conf );
4237 else if ( sequence->IsForVectorPtrLooper() )
4238 sequence->AddAction( PopDataCacheVectorPtr, conf );
4239 else
4240 sequence->AddAction( PopDataCache, conf );
4241 }
4242 } else {
4243 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4244 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4245 iter != end;
4246 ++iter)
4247 {
4248 TConfiguration *conf = iter->fConfiguration->Copy();
4249 if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4250 conf->AddToOffset(offset);
4251 sequence->AddAction( iter->fAction, conf );
4252 }
4253 }
4254 } else {
4255 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4256 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4257 iter != end;
4258 ++iter) {
4259 if ( iter->fConfiguration->fElemId == (UInt_t)element_ids[id].fElemID ) {
4260 TConfiguration *conf = iter->fConfiguration->Copy();
4261 if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4262 conf->AddToOffset(offset);
4263 sequence->AddAction( iter->fAction, conf );
4264 }
4265 }
4266 }
4267 }
4268}
4269
4272{
4273 // Create a sequence containing the subset of the action corresponding to the SteamerElement whose ids is contained in the vector.
4274 // 'offset' is the location of this 'class' within the object (address) that will be passed to ReadBuffer when using this sequence.
4275
4276 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo, element_ids.size(), IsForVectorPtrLooper());
4277
4278 sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
4279
4280 AddToSubSequence(sequence, element_ids, offset, create);
4281
4282 return sequence;
4283}
4284
4286{
4287 // Create a sequence containing the subset of the action corresponding to the SteamerElement whose ids is contained in the vector.
4288 // 'offset' is the location of this 'class' within the object (address) that will be passed to ReadBuffer when using this sequence.
4289
4290 TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo, element_ids.size(), IsForVectorPtrLooper());
4291
4292 sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
4293
4294 for(UInt_t id = 0; id < element_ids.size(); ++id) {
4295 if ( element_ids[id] < 0 ) {
4296 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4297 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4298 iter != end;
4299 ++iter)
4300 {
4301 TConfiguration *conf = iter->fConfiguration->Copy();
4302 if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4303 conf->AddToOffset(offset);
4304 sequence->AddAction( iter->fAction, conf );
4305 }
4306 } else {
4307 TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
4308 for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
4309 iter != end;
4310 ++iter) {
4311 if ( iter->fConfiguration->fElemId == (UInt_t)element_ids[id] ) {
4312 TConfiguration *conf = iter->fConfiguration->Copy();
4313 if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
4314 conf->AddToOffset(offset);
4315 sequence->AddAction( iter->fAction, conf );
4316 }
4317 }
4318 }
4319 }
4320 return sequence;
4321}
4322
4323#if !defined(R__WIN32) && !defined(_AIX)
4324
4325#include <dlfcn.h>
4326
4327#endif
4328
4329typedef void (*voidfunc)();
4330static const char *R__GetSymbolName(voidfunc func)
4331{
4332#if defined(R__WIN32) || defined(__CYGWIN__) || defined(_AIX)
4333 return "not available on this platform";
4334#if 0
4335 MEMORY_BASIC_INFORMATION mbi;
4336 if (!VirtualQuery (func, &mbi, sizeof (mbi)))
4337 {
4338 return 0;
4339 }
4340
4341 HMODULE hMod = (HMODULE) mbi.AllocationBase;
4342 static char moduleName[MAX_PATH];
4343
4344 if (!GetModuleFileNameA (hMod, moduleName, sizeof (moduleName)))
4345 {
4346 return 0;
4347 }
4348 return moduleName;
4349#endif
4350#else
4351 Dl_info info;
4352 if (dladdr((void*)func,&info)==0) {
4353 // Not in a known share library, let's give up
4354 return "name not found";
4355 } else {
4356 //fprintf(stdout,"Found address in %s\n",info.dli_fname);
4357 return info.dli_sname;
4358 }
4359#endif
4360}
4361
4363{
4364 // Add the (potentially negative) delta to all the configuration's offset. This is used by
4365 // TTBranchElement in the case of split sub-object.
4366 // If opt contains 'func', also print the (mangled) name of the function that will be executed.
4367
4368 if (fLoopConfig) {
4369 fLoopConfig->Print();
4370 }
4371 TStreamerInfoActions::ActionContainer_t::const_iterator end = fActions.end();
4372 for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = fActions.begin();
4373 iter != end;
4374 ++iter)
4375 {
4376 iter->fConfiguration->Print();
4377 if (strstr(opt,"func")) {
4378 printf("StreamerInfoAction func: %s\n",R__GetSymbolName((voidfunc)iter->fAction));
4379 }
4380 }
4381}
4382
4383
#define b(i)
Definition RSha256.hxx:100
unsigned short UShort_t
Definition RtypesCore.h:40
int Int_t
Definition RtypesCore.h:45
constexpr Int_t kMaxInt
Definition RtypesCore.h:105
short Version_t
Definition RtypesCore.h:65
long Long_t
Definition RtypesCore.h:54
unsigned int UInt_t
Definition RtypesCore.h:46
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:185
void Warning(const char *location, const char *msgfmt,...)
Use this function in warning situations.
Definition TError.cxx:229
void Fatal(const char *location, const char *msgfmt,...)
Use this function in case of a fatal error. It will abort the program.
Definition TError.cxx:244
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h offset
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h length
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
float xmin
R__EXTERN TVirtualMutex * gInterpreterMutex
@ kIsReferenced
Definition TObject.h:370
Int_t gDebug
Definition TROOT.cxx:597
#define gROOT
Definition TROOT.h:406
static TConfiguredAction GetNumericCollectionReadAction(Int_t type, TConfigSTL *conf)
void(* voidfunc)()
static void AddReadConvertAction(TStreamerInfoActions::TActionSequence *sequence, Int_t newtype, TConfiguration *conf)
static TConfiguredAction GetCollectionReadConvertAction(Int_t newtype, TConfiguration *conf)
static TConfiguredAction GetCollectionReadAction(TVirtualStreamerInfo *info, TStreamerElement *element, Int_t type, UInt_t i, TStreamerInfo::TCompInfo_t *compinfo, Int_t offset)
static const Int_t kRegrouped
#define INLINE_TEMPLATE_ARGS
static const char * R__GetSymbolName(voidfunc func)
static TConfiguredAction GetConvertCollectionReadAction(Int_t oldtype, Int_t newtype, TConfiguration *conf)
static TConfiguredAction GetCollectionWriteAction(TVirtualStreamerInfo *info, TStreamerElement *, Int_t type, UInt_t i, TStreamerInfo::TCompInfo_t *compinfo, Int_t offset)
static TConfiguredAction GetConvertCollectionReadActionFrom(Int_t newtype, TConfiguration *conf)
#define ReadBasicType(name)
#define WriteBasicType(name)
void ReadBuffer(char *&buffer) override
#define R__LOCKGUARD(mutex)
@ kStreamedMemberWise
Definition TBufferFile.h:69
Base class for text-based streamers like TBufferJSON or TBufferXML Special actions list will use meth...
Definition TBufferText.h:20
Buffer base class used for serializing objects.
Definition TBuffer.h:43
virtual void ReadWithNbits(Float_t *ptr, Int_t nbits)=0
virtual void ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue)=0
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)=0
virtual Version_t ReadVersionForMemberWise(const TClass *cl=nullptr)=0
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition TBuffer.cxx:344
virtual UInt_t WriteVersionMemberWise(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual void SetByteCount(UInt_t cntpos, Bool_t packInVersion=kFALSE)=0
virtual void ReadInt(Int_t &i)=0
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:262
virtual UShort_t GetPidOffset() const =0
@ kCannotHandleMemberWiseStreaming
Definition TBuffer.h:76
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=nullptr)=0
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=nullptr)=0
virtual Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object)=0
virtual void ReadFastArrayWithNbits(Float_t *ptr, Int_t n, Int_t nbits)=0
void SetBufferOffset(Int_t offset=0)
Definition TBuffer.h:93
virtual void WriteFastArray(const Bool_t *b, Long64_t n)=0
virtual void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue)=0
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)=0
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=nullptr)=0
Int_t Length() const
Definition TBuffer.h:100
virtual void StreamObject(void *obj, const std::type_info &typeinfo, const TClass *onFileClass=nullptr)=0
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:81
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=nullptr) const
Definition TClass.h:607
Bool_t CanSplit() const
Return true if the data member of this TClass can be saved separately.
Definition TClass.cxx:2386
void * NewArray(Long_t nElements, ENewType defConstructor=kClassNew) const
Return a pointer to a newly allocated array of objects of this class.
Definition TClass.cxx:5260
EState GetState() const
Definition TClass.h:488
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5045
Bool_t HasCustomStreamerMember() const
The class has a Streamer method and it is implemented by the user or an older (not StreamerInfo based...
Definition TClass.h:508
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5771
void DeleteArray(void *ary, Bool_t dtorOnly=kFALSE)
Explicitly call operator delete[] for an array.
Definition TClass.cxx:5596
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0, Bool_t isTransient=kFALSE) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition TClass.cxx:4666
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition TClass.cxx:2964
TVirtualStreamerInfo * GetConversionStreamerInfo(const char *onfile_classname, Int_t version) const
Return a Conversion StreamerInfo from the class 'classname' for version number 'version' to this clas...
Definition TClass.cxx:7153
@ kEmulated
Definition TClass.h:125
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
A ROOT file is an on-disk file, usually with extension .root, that stores objects in a file-system-li...
Definition TFile.h:53
Int_t GetVersion() const
Definition TFile.h:245
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:48
static TClass * Class()
An array of TObjects.
Definition TObjArray.h:31
Int_t GetEntriesFast() const
Definition TObjArray.h:58
void AddAt(TObject *obj, Int_t idx) override
Add object at position ids.
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
TObject * At(Int_t idx) const override
Definition TObjArray.h:164
Mother of all ROOT objects.
Definition TObject.h:41
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:456
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:199
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition TObject.cxx:474
@ kIsOnHeap
object is on heap
Definition TObject.h:81
@ kNotDeleted
object has not been deleted
Definition TObject.h:82
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:225
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:991
static TClass * Class()
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:798
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition TObject.cxx:809
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition TProcessID.h:74
void PutObjectWithID(TObject *obj, UInt_t uid=0)
stores the object at the uid th slot in the table of objects The object uniqued is set as well as its...
const char * GetErrorMessage() const
static TClass * Class()
Int_t GetNewType() const
virtual Int_t GetSize() const
Returns size of this element in bytes.
Int_t GetType() const
virtual const char * GetFullName() const
Return element name including dimensions, if any Note that this function stores the name into a stati...
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
virtual ULongptr_t GetMethod() const
Int_t GetArrayDim() const
TMemberStreamer * GetStreamer() const
Return the local streamer object.
Double_t GetXmax() const
TClass * GetNewClass() const
Int_t GetArrayLength() const
Double_t GetFactor() const
const char * GetTypeName() const
TClass * IsA() const override
Double_t GetXmin() const
Int_t GetOffset() const
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
virtual Bool_t HasCounter() const
void GetSequenceType(TString &type) const
Fill type with the string representation of sequence information including 'cached',...
static TActionSequence * CreateReadMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by '...
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
void Print(Option_t *="") const override
This method must be overridden when a class wants to print itself.
static TActionSequence * CreateWriteMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by '...
SequencePtr(*)(TStreamerInfo *info, TVirtualCollectionProxy *collectionProxy, TClass *originalClass) SequenceGetter_t
void AddToSubSequence(TActionSequence *sequence, const TIDs &element_ids, Int_t offset, SequenceGetter_t create)
TActionSequence * CreateSubSequence(const std::vector< Int_t > &element_ids, size_t offset)
void AddAction(action_t action, TConfiguration *conf)
TLoopConfiguration * Copy() const override
TAssocLoopConfig(TVirtualCollectionProxy *proxy, Bool_t)
void * GetFirstAddress(void *start, const void *) const override
TConfNoFactor(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, Int_t nbits)
TConfSTLNoFactor(TConfigSTL *orig, Int_t nbits)
TConfSTLWithFactor(TConfigSTL *orig, Double_t factor, Double_t xmin)
TConfWithFactor(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, Double_t factor, Double_t xmin)
TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TMemberStreamer *streamer, const char *type_name, Bool_t isbase)
TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, TMemberStreamer *streamer, const char *type_name, Bool_t isbase)
TVirtualCollectionProxy::CreateIterators_t fCreateWriteIterators
TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, const char *type_name, Bool_t isbase)
TVirtualCollectionProxy::CreateIterators_t fCreateIterators
TVirtualCollectionProxy::DeleteIterator_t fDeleteIterator
TVirtualCollectionProxy::DeleteTwoIterators_t fDeleteTwoIterators
TVirtualCollectionProxy::CopyIterator_t fCopyIterator
TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, TClass *newClass, const char *type_name, Bool_t isbase)
TConfigurationPushDataCache(TVirtualStreamerInfo *info, TVirtualArray *onfileObject, Int_t offset)
void PrintDebug(TBuffer &buffer, void *object) const override
void PrintDebug(TBuffer &b, void *addr) const override
TConfigurationUseCache(TVirtualStreamerInfo *info, TConfiguredAction &action, Bool_t repeat)
Base class of the Configurations.
virtual void PrintDebug(TBuffer &buffer, void *object) const
TVirtualStreamerInfo * fInfo
TStreamerInfo form which the action is derived.
Int_t fOffset
Offset within the object.
TCompInfo_t * fCompInfo
Access to compiled information (for legacy code)
UInt_t fLength
Number of element in a fixed length array.
UInt_t fElemId
Identifier of the TStreamerElement.
void PrintDebug(TBuffer &buffer, void *object) const
TLoopConfiguration * Copy() const override
void * GetFirstAddress(void *start_collection, const void *end_collection) const override
TVirtualCollectionProxy::CopyIterator_t fCopyIterator
TVirtualCollectionProxy::DeleteIterator_t fDeleteIterator
TGenericLoopConfig(TVirtualCollectionProxy *proxy, Bool_t read)
Base class of the Configurations for the member wise looping routines.
virtual TVirtualCollectionProxy * GetCollectionProxy() const
virtual TLoopConfiguration * Copy() const =0
TLoopConfiguration * Copy() const override
void * GetFirstAddress(void *start, const void *) const override
TVectorLoopConfig(TVirtualCollectionProxy *proxy, Long_t increment, Bool_t)
TClass * fClass
Not Owned.
TMemberStreamer * fStreamer
Not Owned.
TStreamerElement * fElem
Not Owned.
TClass * fNewClass
Not Owned.
Describes a persistent version of a class.
Int_t fNVirtualInfoLoc
! Number of virtual info location to update.
Int_t ReadBufferSTL(TBuffer &b, TVirtualCollectionProxy *cont, Int_t nc, Int_t eoffset, Bool_t v7=kTRUE)
The STL vector/list is deserialized from the buffer b.
void AddWriteAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo)
Int_t fNfulldata
!number of elements
TCompInfo * fComp
![fNslots with less than fElements->GetEntries()*1.5 used] Compiled info
TStreamerInfoActions::TActionSequence * GetWriteMemberWiseActions(Bool_t forCollection)
TStreamerInfoActions::TActionSequence * fWriteMemberWiseVecPtr
! List of write action resulting from the compilation for use in member wise streaming.
TStreamerInfoActions::TActionSequence * fReadText
! List of text read action resulting from the compilation, used for JSON.
void ls(Option_t *option="") const override
List the TStreamerElement list and also the precomputed tables if option contains the string "incOrig...
void AddReadTextAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read text action for the given element.
TCompInfo ** fCompFull
![fElements->GetEntries()]
TObjArray * fElements
Array of TStreamerElements.
void AddReadMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read action for the given element.
TStreamerInfoActions::TActionSequence * fReadMemberWise
! List of read action resulting from the compilation for use in member wise streaming.
Int_t fNdata
!number of optimized elements
TStreamerInfoActions::TActionSequence * fReadMemberWiseVecPtr
! List of read action resulting from the compilation for use in member wise streaming.
TStreamerInfoActions::TActionSequence * fReadObjectWise
! List of read action resulting from the compilation.
TClass * fClass
!pointer to class
TCompInfo ** fCompOpt
![fNdata]
TClass * GetClass() const override
static std::atomic< Int_t > fgCount
Number of TStreamerInfo instances.
void AddWriteTextAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo)
void ComputeSize()
Compute total size of all persistent elements of the class.
void AddReadAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read action for the given element.
void AddWriteMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo)
This is for streaming via a TClonesArray (or a vector of pointers of this type).
Int_t fNumber
!Unique identifier
TStreamerInfoActions::TActionSequence * fWriteObjectWise
! List of write action resulting from the compilation.
Int_t fSize
!size of the persistent class
void Compile() override
loop on the TStreamerElement list regroup members with same type Store predigested information into l...
Int_t ReadBufferSkip(TBuffer &b, const T &arrptr, const TCompInfo *compinfo, Int_t kase, TStreamerElement *aElement, Int_t narr, Int_t eoffset)
Skip an element.
TStreamerInfoActions::TActionSequence * fWriteMemberWise
! List of write action resulting from the compilation for use in member wise streaming.
Int_t fNslots
!total number of slots in fComp.
Version_t fOldVersion
! Version of the TStreamerInfo object read from the file
TStreamerInfoActions::TActionSequence * fWriteText
! List of text write action resulting for the compilation, used for JSON.
TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Bool_t forCollection)
Basic string class.
Definition TString.h:139
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition TString.cxx:1163
const char * Data() const
Definition TString.h:376
@ kTrailing
Definition TString.h:276
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
TClassRef fClass
RAII helper class that ensures that PushProxy() / PopProxy() are called when entering / leaving a C++...
Defines a common interface to inspect/change the contents of an object that represents a collection.
virtual Int_t GetProperties() const
Return miscallenous properties of the proxy (see TVirtualCollectionProxy::EProperty)
virtual ULong_t GetIncrement() const =0
Return the offset between two consecutive in-memory values (which depends on the sizeof() and alignme...
virtual TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Int_t version)=0
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
*begin_arena and *end_arena should contain the location of a memory arena of size fgIteratorArenaSize...
virtual EDataType GetType() const =0
If the value type is a fundamental data type, return its type (see enumeration EDataType).
@ kCustomAlloc
The collection has a custom allocator.
void *(* CopyIterator_t)(void *dest, const void *source)
Copy the iterator source into dest.
void *(* Next_t)(void *iter, const void *end)
iter and end should be pointers to an iterator to be incremented and an iterator that points to the e...
virtual TClass * GetValueClass() const =0
If the value type is a user-defined class, return a pointer to the TClass representing the value type...
virtual void Commit(void *)=0
Commits pending elements in a staging area (see Allocate() for more information).
virtual Int_t GetCollectionType() const =0
Return the type of the proxied collection (see enumeration TClassEdit::ESTLType)
virtual Next_t GetFunctionNext(Bool_t read=kTRUE)=0
Return a pointer to a function that can advance an iterator (see Next_t).
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual UInt_t Size() const =0
Return the current number of elements in the container.
void(* DeleteTwoIterators_t)(void *begin, void *end)
void(* DeleteIterator_t)(void *iter)
If the size of the iterator is greater than fgIteratorArenaSize, call delete on the addresses; otherw...
static const Int_t fgIteratorArenaSize
The size of a small buffer that can be allocated on the stack to store iterator-specific information.
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Return a pointer to a function that can create an iterator pair, where each iterator points to the be...
virtual void * Allocate(UInt_t n, Bool_t forceDelete)=0
Allocates space for storing at least n elements.
virtual TStreamerInfoActions::TActionSequence * GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)=0
virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read=kTRUE)=0
Return a pointer to a function that can delete an iterator (pair) (see DeleteIterator_t).
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)=0
Return a pointer to a function that can copy an iterator (see CopyIterator_t).
virtual Bool_t HasPointers() const =0
Return true if the content is of type 'pointer to'.
virtual TClass * GetCollectionClass() const
Return a pointer to the TClass representing the proxied container class.
static void * Next(void *iter, const void *end)
static void * CopyIterator(void *dest, const void *source)
Abstract Interface class describing Streamer information for one class.
static Bool_t GetStreamMemberWise()
Return whether the TStreamerInfos will save the collections in "member-wise" order whenever possible.
@ kUChar
Equal to TDataType's kchar.
TClass * IsA() const override
static Bool_t CanOptimize()
static function returning true if optimization can be on
virtual TObjArray * GetElements() const =0
virtual Int_t GetClassVersion() const =0
struct void * fTypeName
Definition cppyy.h:9
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
@ kSTLbitset
Definition ESTLType.h:37
@ kSTLmap
Definition ESTLType.h:33
@ kSTLunorderedmultiset
Definition ESTLType.h:43
@ kSTLset
Definition ESTLType.h:35
@ kSTLmultiset
Definition ESTLType.h:36
@ kSTLvector
Definition ESTLType.h:30
@ kSTLunorderedmultimap
Definition ESTLType.h:45
@ kSTLunorderedset
Definition ESTLType.h:42
@ kSTLunorderedmap
Definition ESTLType.h:44
@ kSTLmultimap
Definition ESTLType.h:34
void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t, UInt_t)
Int_t PushDataCacheVectorPtr(TBuffer &b, void *, const void *, const TConfiguration *conf)
Int_t WriteTextStreamer(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t PopDataCache(TBuffer &b, void *, const TConfiguration *)
void ReadSTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
void ReadSTLObjectWiseFastArrayV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
Int_t ReadBasicType< BitsMarker >(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t ReadStreamerLoop(TBuffer &buf, void *addr, const TConfiguration *config)
Direct copy of code from TStreamerInfo::WriteBufferAux, potentially can be used later for non-text st...
Int_t WriteTextBaseClass(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t GenericWriteAction(TBuffer &buf, void *addr, const TConfiguration *config)
void ReadArraySTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
Int_t PopDataCacheVectorPtr(TBuffer &b, void *, const void *, const TConfiguration *)
Int_t ReadTextStreamer(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t GenericReadAction(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t WriteTextTObject(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t ReadBasicType_WithFactor(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t ReadTextBaseClass(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
Int_t ReadSTL(TBuffer &buf, void *addr, const TConfiguration *conf)
Int_t ReadTextTObject(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t PushDataCache(TBuffer &b, void *, const TConfiguration *conf)
Int_t UseCache(TBuffer &b, void *addr, const TConfiguration *conf)
std::vector< TIDNode > TIDs
Int_t WriteLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
void ReadSTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
Int_t WriteTextTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t ReadTextObject(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t UseCacheVectorLoop(TBuffer &b, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf)
Int_t ReadTextTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t WriteSTLp(TBuffer &buf, void *addr, const TConfiguration *config)
Direct copy of code from TStreamerInfo::WriteBufferAux, potentially can be used later for non-text st...
void ReadSTLObjectWiseFastArray(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t, UInt_t)
Int_t ReadTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t ReadBasicType_NoFactor(TBuffer &buf, void *addr, const TConfiguration *config)
bool IsDefaultVector(TVirtualCollectionProxy &proxy)
Int_t ReadLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
Int_t ReadTObject(TBuffer &buf, void *addr, const TConfiguration *config)
void ReadSTLObjectWiseStreamerV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
void ReadArraySTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
void HandleReferencedTObject(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t PopDataCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *, const TConfiguration *)
Int_t WriteStreamerLoop(TBuffer &buf, void *addr, const TConfiguration *config)
Direct copy of code from TStreamerInfo::WriteBufferAux, potentially can be used later for non-text st...
Int_t PushDataCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
Int_t ReadTextTObjectBase(TBuffer &buf, void *addr, const TConfiguration *config)
ESelectLooper SelectLooper(TVirtualCollectionProxy &proxy)
Int_t ReadSTLp(TBuffer &buf, void *addr, const TConfiguration *config)
Direct copy of code from TStreamerInfo::WriteBufferAux, potentially can be used later for non-text st...
Int_t ReadTString(TBuffer &buf, void *addr, const TConfiguration *config)
Int_t UseCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
TVirtualCollectionProxy::Next_t Next_t
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
static void Action(TBuffer &buf, void *addr, Int_t nvalues)
static void SimpleRead(TBuffer &buf, void *addr, Int_t nvalues)
static Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
static void SimpleReadDouble32(TBuffer &buf, void *addr, Int_t nvalues)
static Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
static void SimpleReadFloat16(TBuffer &buf, void *addr, Int_t nvalues)
static Int_t ReadNumericalCollection(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *)
static Int_t ReadBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t WriteBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t GenericRead(TBuffer &buf, void *, const void *, const TLoopConfiguration *loopconf, const TConfiguration *config)
static void SimpleReadFloat16(TBuffer &buf, void *addr)
static Int_t ReadNumericalCollection(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t GenericWrite(TBuffer &buf, void *, const void *, const TLoopConfiguration *loopconf, const TConfiguration *config)
static Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
static void SimpleRead(TBuffer &buf, void *addr)
static Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
static void SimpleReadDouble32(TBuffer &buf, void *addr)
static Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
TBitsConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset=0)
void PrintDebug(TBuffer &, void *) const override
TGenericConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset=0)
void PrintDebug(TBuffer &, void *) const override
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t GenericWrite(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ConvertCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
static Int_t GenericRead(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
static Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
static Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t GenericRead(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
static Int_t GenericWrite(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)