Logo ROOT   6.10/09
Reference Guide
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"
13 #include "TStreamerInfoActions.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 "TMemberStreamer.h"
22 #include "TError.h"
23 #include "TClassEdit.h"
25 #include "TProcessID.h"
26 
28 
29 // More possible optimizations:
30 // Avoid call the virtual version of TBuffer::ReadInt and co.
31 // Merge the Reading of the version and the looking up or the StreamerInfo
32 // Avoid if (bytecnt) inside the CheckByteCount routines and avoid multiple (mostly useless nested calls)
33 // Try to avoid if statement on onfile class being set (TBufferFile::ReadClassBuffer).
34 
35 using namespace TStreamerInfoActions;
36 
37 #ifdef _AIX
38 # define INLINE_TEMPLATE_ARGS
39 #else
40 # define INLINE_TEMPLATE_ARGS inline
41 #endif
42 
43 
44 namespace TStreamerInfoActions
45 {
46  template <typename From>
47  struct WithFactorMarker {
48  typedef From Value_t;
49  };
50 
51  template <typename From>
52  struct NoFactorMarker {
53  typedef From Value_t;
54  };
55 
56  struct BitsMarker {
57  typedef UInt_t Value_t;
58  };
59 
61  {
62  // Add the (potentially negative) delta to all the configuration's offset. This is used by
63  // TBranchElement in the case of split sub-object.
64 
65  fOffset += delta;
66  }
67 
68  void TConfiguredAction::PrintDebug(TBuffer &buf, void *addr) const
69  {
70  // Inform the user what we are about to stream.
71 
72  // Idea, we should find a way to print the name of the function
73  if (fConfiguration) fConfiguration->PrintDebug(buf,addr);
74  }
75 
76  void TConfiguration::Print() const
77  {
78  // Inform the user what we are about to stream.
79 
80  TStreamerInfo *info = (TStreamerInfo*)fInfo;
81  TStreamerElement *aElement = fCompInfo->fElem;
82  TString sequenceType;
83  aElement->GetSequenceType(sequenceType);
84 
85  printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
86  " %s, offset=%d (%s)\n",
87  info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
88  aElement->ClassName(), fOffset, sequenceType.Data());
89  }
90 
91  void TConfiguration::PrintDebug(TBuffer &buf, void *addr) const
92  {
93  // Inform the user what we are about to stream.
94 
95  if (gDebug > 1) {
96  // Idea: We should print the name of the action function.
97  TStreamerInfo *info = (TStreamerInfo*)fInfo;
98  TStreamerElement *aElement = fCompInfo->fElem;
99  TString sequenceType;
100  aElement->GetSequenceType(sequenceType);
101 
102  printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
103  " %s, bufpos=%d, arr=%p, offset=%d (%s)\n",
104  info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
105  aElement->ClassName(), buf.Length(), addr, fOffset, sequenceType.Data());
106  }
107  }
108 
110  {
111  // Inform the user what we are about to stream.
112 
113  printf("TLoopConfiguration: unconfigured\n");
114  }
115 
116 
117  struct TGenericConfiguration : TConfiguration {
118  // Configuration of action using the legacy code.
119  // Mostly to cancel out the PrintDebug.
120  public:
121  TGenericConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset = 0) : TConfiguration(info,id,compinfo,offset) {};
122  void PrintDebug(TBuffer &, void *) const {
123  // Since we call the old code, it will print the debug statement.
124  }
125 
126  virtual TConfiguration *Copy() { return new TGenericConfiguration(*this); }
127  };
128 
129  struct TBitsConfiguration : TConfiguration {
130  // Configuration of action handling kBits.
131  // In this case we need to know both the location
132  // of the member (fBits) and the start of the object
133  // (its TObject part to be exact).
134 
135  Int_t fObjectOffset; // Offset of the TObject part within the object
136 
137  TBitsConfiguration(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset = 0) : TConfiguration(info,id,compinfo,offset),fObjectOffset(0) {};
138  void PrintDebug(TBuffer &, void *) const {
139  TStreamerInfo *info = (TStreamerInfo*)fInfo;
140  TStreamerElement *aElement = fCompInfo->fElem;
141  TString sequenceType;
142  aElement->GetSequenceType(sequenceType);
143 
144  printf("StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
145  " %s, offset=%d (%s)\n",
146  info->GetClass()->GetName(), aElement->GetName(), fElemId, fCompInfo->fType,
147  aElement->ClassName(), fOffset, sequenceType.Data());
148  }
149 
150  void AddToOffset(Int_t delta)
151  {
152  // Add the (potentially negative) delta to all the configuration's offset. This is used by
153  // TBranchElement in the case of split sub-object.
154 
155  fOffset += delta;
156  fObjectOffset = 0;
157  }
158 
159  virtual TConfiguration *Copy() { return new TBitsConfiguration(*this); }
160 
161  };
162 
163  Int_t GenericReadAction(TBuffer &buf, void *addr, const TConfiguration *config)
164  {
165  char *obj = (char*)addr;
166  TGenericConfiguration *conf = (TGenericConfiguration*)config;
167  return ((TStreamerInfo*)conf->fInfo)->ReadBuffer(buf, &obj, &(conf->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ 1, config->fOffset, 2);
168  }
169 
170  Int_t GenericWriteAction(TBuffer &buf, void *addr, const TConfiguration *config)
171  {
172  char *obj = (char*)addr;
173  TGenericConfiguration *conf = (TGenericConfiguration*)config;
174  return ((TStreamerInfo*)conf->fInfo)->WriteBufferAux(buf, &obj, &(conf->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ 1, config->fOffset, 2);
175  }
176 
177  template <typename T>
179  {
180  T *x = (T*)( ((char*)addr) + config->fOffset );
181  // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
182  buf >> *x;
183  return 0;
184  }
185 
186  void HandleReferencedTObject(TBuffer &buf, void *addr, const TConfiguration *config) {
187  TBitsConfiguration *conf = (TBitsConfiguration*)config;
188  UShort_t pidf;
189  buf >> pidf;
190  pidf += buf.GetPidOffset();
191  TProcessID *pid = buf.ReadProcessID(pidf);
192  if (pid!=0) {
193  TObject *obj = (TObject*)( ((char*)addr) + conf->fObjectOffset);
194  UInt_t gpid = pid->GetUniqueID();
195  UInt_t uid;
196  if (gpid>=0xff) {
197  uid = obj->GetUniqueID() | 0xff000000;
198  } else {
199  uid = ( obj->GetUniqueID() & 0xffffff) + (gpid<<24);
200  }
201  obj->SetUniqueID(uid);
202  pid->PutObjectWithID(obj);
203  }
204  }
205 
206  template <>
208  {
209  UInt_t *x = (UInt_t*)( ((char*)addr) + config->fOffset );
210  // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
211  // Idea: This code really belongs inside TBuffer[File]
212  buf >> *x;
213 
214  if ((*x & kIsReferenced) != 0) {
215  HandleReferencedTObject(buf,addr,config);
216  }
217  return 0;
218  }
219 
220  template <typename T>
222  {
223  T *x = (T*)( ((char*)addr) + config->fOffset );
224  // Idea: Implement buf.ReadBasic/Primitive to avoid the return value
225  buf << *x;
226  return 0;
227  }
228 
229  class TConfWithFactor : public TConfiguration {
230  // Configuration object for the Float16/Double32 where a factor has been specified.
231  public:
232  Double_t fFactor;
233  Double_t fXmin;
234  TConfWithFactor(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, Double_t factor, Double_t xmin) : TConfiguration(info,id,compinfo,offset),fFactor(factor),fXmin(xmin) {};
235  virtual TConfiguration *Copy() { return new TConfWithFactor(*this); }
236  };
237 
238  template <typename T>
240  {
241  // Stream a Float16 or Double32 where a factor has been specified.
242  //a range was specified. We read an integer and convert it back to a double.
243 
244  TConfWithFactor *conf = (TConfWithFactor *)config;
245  buf.ReadWithFactor((T*)( ((char*)addr) + config->fOffset ), conf->fFactor, conf->fXmin);
246  return 0;
247  }
248 
249  class TConfNoFactor : public TConfiguration {
250  // Configuration object for the Float16/Double32 where a factor has been specified.
251  public:
252  Int_t fNbits;
253  TConfNoFactor(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, Int_t nbits) : TConfiguration(info,id,compinfo,offset),fNbits(nbits) {};
254  virtual TConfiguration *Copy() { return new TConfNoFactor(*this); }
255  };
256 
257  template <typename T>
259  {
260  // Stream a Float16 or Double32 where a factor has not been specified.
261 
262  TConfNoFactor *conf = (TConfNoFactor *)config;
263  Int_t nbits = conf->fNbits;
264 
265  buf.ReadWithNbits( (T*)( ((char*)addr) + config->fOffset ), nbits );
266  return 0;
267  }
268 
270  {
271  // Read in a TString object.
272 
273  // Idea: We could separate the TString Streamer in its two parts and
274  // avoid the if (buf.IsReading()) and try having it inlined.
275  ((TString*)(((char*)addr)+config->fOffset))->TString::Streamer(buf);
276  return 0;
277  }
278 
280  {
281  // Read in a TObject object part.
282 
283  // Idea: We could separate the TObject Streamer in its two parts and
284  // avoid the if (buf.IsReading()).
285  ((TObject*)(((char*)addr)+config->fOffset))->TObject::Streamer(buf);
286  return 0;
287  }
288 
289  INLINE_TEMPLATE_ARGS Int_t ReadTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
290  {
291  // Read in a TNamed object part.
292  // Since the TNamed streamer is solely delegating back to the StreamerInfo we
293  // can skip the streamer.
294 
295  // Idea: We could extract the code from ReadClassBuffer and avoid one function
296  // code.
297  static const TClass *TNamed_cl = TNamed::Class();
298  return buf.ReadClassBuffer(TNamed_cl,(((char*)addr)+config->fOffset));
299  }
300 
301  class TConfigSTL : public TConfiguration {
302  // Configuration object for the kSTL case
303  private:
304  void Init() {
305  TVirtualCollectionProxy *proxy = fNewClass->GetCollectionProxy();
306  if (proxy) {
307  fCreateIterators = proxy->GetFunctionCreateIterators();
308  fCopyIterator = proxy->GetFunctionCopyIterator();
309  fDeleteIterator = proxy->GetFunctionDeleteIterator();
310  fDeleteTwoIterators = proxy->GetFunctionDeleteTwoIterators();
311  }
312  }
313 
314  public:
315  TClass *fOldClass; // Class of the content on file
316  TClass *fNewClass; // Class of the content in memory.
317  TMemberStreamer *fStreamer;
318  const char *fTypeName; // Type name of the member as typed by ther user.
319  Bool_t fIsSTLBase; // aElement->IsBase() && aElement->IsA()!=TStreamerBase::Class()
320 
325 
326  TConfigSTL(TVirtualStreamerInfo *info, UInt_t id, TCompInfo_t *compinfo, Int_t offset, UInt_t length, TClass *oldClass, const char *type_name, Bool_t isbase) :
327  TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(oldClass), fStreamer(0), fTypeName(type_name), fIsSTLBase(isbase),
328  fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
329 
330  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) :
331  TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(newClass), fStreamer(0), fTypeName(type_name), fIsSTLBase(isbase),
332  fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
333 
334  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) :
335  TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(oldClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
336  fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
337 
338  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) :
339  TConfiguration(info,id,compinfo,offset,length), fOldClass(oldClass), fNewClass(newClass), fStreamer(streamer), fTypeName(type_name), fIsSTLBase(isbase),
340  fCreateIterators(0), fCopyIterator(0), fDeleteIterator(0), fDeleteTwoIterators(0) { Init(); }
341 
342  virtual TConfiguration *Copy() { return new TConfigSTL(*this); }
343  };
344 
345  class TConfSTLWithFactor : public TConfigSTL {
346  // Configuration object for the Float16/Double32 where a factor has been specified.
347  public:
348  Double_t fFactor;
349  Double_t fXmin;
350  TConfSTLWithFactor(TConfigSTL *orig, Double_t factor, Double_t xmin) : TConfigSTL(*orig),fFactor(factor),fXmin(xmin) {};
351  virtual TConfiguration *Copy() { return new TConfSTLWithFactor(*this); }
352  };
353 
354  class TConfSTLNoFactor : public TConfigSTL {
355  // Configuration object for the Float16/Double32 where a factor has been specified.
356  public:
357  Int_t fNbits;
358  TConfSTLNoFactor(TConfigSTL *orig, Int_t nbits) : TConfigSTL(*orig),fNbits(nbits) {};
359  virtual TConfiguration *Copy() { return new TConfSTLNoFactor(*this); }
360  };
361 
362  class TVectorLoopConfig : public TLoopConfiguration {
363  // Base class of the Configurations used in member wise streaming.
364  protected:
365  public:
366  Long_t fIncrement; // Either a value to increase the cursor by and
367  public:
368  TVectorLoopConfig(Long_t increment, Bool_t /* read */) : fIncrement(increment) {};
369  //virtual void PrintDebug(TBuffer &buffer, void *);
370  virtual ~TVectorLoopConfig() {};
371  void Print() const
372  {
373  printf("TVectorLoopConfig: increment=%ld\n",fIncrement);
374  }
375 
376  void* GetFirstAddress(void *start, const void * /* end */) const
377  {
378  // Return the address of the first element of the collection.
379 
380  return start;
381  }
382 
383  virtual TLoopConfiguration* Copy() { return new TVectorLoopConfig(*this); }
384  };
385 
386  class TAssocLoopConfig : public TLoopConfiguration {
387  // Base class of the Configurations used in member wise streaming.
388  protected:
389  public:
390  TVirtualCollectionProxy *fProxy;
391  public:
392  TAssocLoopConfig(TVirtualCollectionProxy *proxy, Bool_t /* read */) : fProxy(proxy) {};
393  //virtual void PrintDebug(TBuffer &buffer, void *);
394  virtual ~TAssocLoopConfig() {};
395  void Print() const
396  {
397  printf("TAssocLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
398  }
399  virtual TLoopConfiguration* Copy() { return new TAssocLoopConfig(*this); }
400 
401  void* GetFirstAddress(void *start, const void * /* end */) const
402  {
403  // Return the address of the first element of the collection.
404 
405  R__ASSERT(0);
406 // char iterator[TVirtualCollectionProxy::fgIteratorArenaSize];
407 // void *iter = genloopconfig->fCopyIterator(&iterator,start_collection);
408 // arr0 = genloopconfig->fNext(iter,end_collection);
409 // if (iter != &iterator[0]) {
410 // genloopconfig->fDeleteIterator(iter);
411 // }
412  return start;
413  }
414  };
415 
416  class TGenericLoopConfig : public TLoopConfiguration {
417  // Configuration object for the generic case of member wise streaming looping.
418  private:
419  void Init(Bool_t read) {
420  if (fProxy) {
421  if (fProxy->HasPointers()) {
425  } else {
426  fNext = fProxy->GetFunctionNext(read);
427  fCopyIterator = fProxy->GetFunctionCopyIterator(read);
428  fDeleteIterator = fProxy->GetFunctionDeleteIterator(read);
429  }
430  }
431  }
432  public:
433  TVirtualCollectionProxy *fProxy;
437 
438  TGenericLoopConfig(TVirtualCollectionProxy *proxy, Bool_t read) : fProxy(proxy), fNext(0), fCopyIterator(0), fDeleteIterator(0)
439  {
440  Init(read);
441  }
442  virtual ~TGenericLoopConfig() {};
443  void Print() const
444  {
445  printf("TGenericLoopConfig: proxy=%s\n",fProxy->GetCollectionClass()->GetName());
446  }
447  virtual TLoopConfiguration* Copy() { return new TGenericLoopConfig(*this); }
448 
449  void* GetFirstAddress(void *start_collection, const void *end_collection) const
450  {
451  // Return the address of the first element of the collection.
452 
454  void *iter = fCopyIterator(&iterator,start_collection);
455  void *arr0 = fNext(iter,end_collection);
456  if (iter != &iterator[0]) {
457  fDeleteIterator(iter);
458  }
459  return arr0;
460  }
461  };
462 
464  {
465  // Collection was saved member-wise
466 
467  TConfigSTL *config = (TConfigSTL*)conf;
469 
470  if( vers >= 8 ) {
471 
472  TClass *oldClass = config->fOldClass;
473 
474  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
475  if (!oldProxy) {
476  // Missing information, broken file ... give up
477  return;
478  }
479  TClass *valueClass = oldProxy->GetValueClass();
480  Version_t vClVersion = buf.ReadVersionForMemberWise( valueClass );
481 
482  TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
483  Int_t nobjects;
484  buf.ReadInt(nobjects);
485  void* alternative = oldProxy->Allocate(nobjects,true);
486  if (nobjects) {
487  TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
488 
491  void *begin = &(startbuf[0]);
492  void *end = &(endbuf[0]);
493  config->fCreateIterators(alternative, &begin, &end, oldProxy);
494  // We can not get here with a split vector of pointer, so we can indeed assume
495  // that actions->fConfiguration != null.
496  buf.ApplySequence(*actions, begin, end);
497  if (begin != &(startbuf[0])) {
498  // assert(end != endbuf);
499  config->fDeleteTwoIterators(begin,end);
500  }
501  }
502  oldProxy->Commit(alternative);
503 
504  } else {
505 
506  TClass *oldClass = config->fOldClass;
507 
508  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
509  if (!oldProxy) {
510  // Missing information, broken file ... give up
511  return;
512  }
513 
514  TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)addr );
515  Int_t nobjects;
516  buf.ReadInt(nobjects);
517  void* env = oldProxy->Allocate(nobjects,true);
518 
519  if (nobjects || vers < 7 ) {
520  // coverity[dereference] since this is a member streaming action by definition the collection contains objects.
521  TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
522 
523  subinfo->ReadBufferSTL(buf, oldProxy, nobjects, /* offset */ 0, /* v7 */ kFALSE);
524  }
525  oldProxy->Commit(env);
526  }
527  }
528 
530  {
531  // Collection was saved member-wise
532 
533  TConfigSTL *config = (TConfigSTL*)conf;
535 
536  if( vers >= 8 ) {
537 
538  TClass *oldClass = config->fOldClass;
539 
540  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
541  if (!oldProxy) {
542  // Missing information, broken file ... give up
543  return;
544  }
545  TClass *valueClass = oldProxy->GetValueClass();
546  Version_t vClVersion = buf.ReadVersionForMemberWise( valueClass );
547 
548  TActionSequence *actions = oldProxy->GetReadMemberWiseActions( vClVersion );
549 
550  int objectSize = oldClass->Size();
551  char *obj = (char*)addr;
552  char *endobj = obj + conf->fLength*objectSize;
553 
554  for(; obj<endobj; obj+=objectSize) {
555  Int_t nobjects;
556  buf.ReadInt(nobjects);
557  TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
558  void* alternative = oldProxy->Allocate(nobjects,true);
559  if (nobjects) {
562  void *begin = &(startbuf[0]);
563  void *end = &(endbuf[0]);
564  config->fCreateIterators(alternative, &begin, &end, oldProxy);
565  // We can not get here with a split vector of pointer, so we can indeed assume
566  // that actions->fConfiguration != null.
567  buf.ApplySequence(*actions, begin, end);
568  if (begin != &(startbuf[0])) {
569  // assert(end != endbuf);
570  config->fDeleteTwoIterators(begin,end);
571  }
572  }
573  oldProxy->Commit(alternative);
574  }
575 
576  } else {
577 
578  TClass *oldClass = config->fOldClass;
579 
580  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
581  if (!oldProxy) {
582  // Missing information, broken file ... give up
583  return;
584  }
585 
586  int objectSize = oldClass->Size();
587  char *obj = (char*)addr;
588  char *endobj = obj + conf->fLength*objectSize;
589 
590  for(; obj<endobj; obj+=objectSize) {
591  TVirtualCollectionProxy::TPushPop helper( oldProxy, (char*)obj );
592  Int_t nobjects;
593  buf.ReadInt(nobjects);
594  void* env = oldProxy->Allocate(nobjects,true);
595 
596  if (nobjects || vers < 7 ) {
597  // coverity[dereference] since this is a member streaming action by definition the collection contains objects.
598  TStreamerInfo *subinfo = (TStreamerInfo*)oldProxy->GetValueClass()->GetStreamerInfo( 0 );
599 
600  subinfo->ReadBufferSTL(buf, oldProxy, nobjects, /* offset */ 0, /* v7 */ kFALSE);
601  }
602  oldProxy->Commit(env);
603  }
604  }
605  }
606 
608  {
609  // Collection was saved member-wise
610 
611  TConfigSTL *config = (TConfigSTL*)conf;
612 
614 
615  TClass *newClass = config->fNewClass;
616  TClass *oldClass = config->fOldClass;
617 
618  if( vers < 8 ) {
619  Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
620  vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
621  } else {
622 
623  Version_t vClVersion = buf.ReadVersionForMemberWise( oldClass->GetCollectionProxy()->GetValueClass() );
624 
625  TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
626  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
627 
628  TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)addr );
629  Int_t nobjects;
630  buf.ReadInt(nobjects);
631  void* alternative = newProxy->Allocate(nobjects,true);
632  if (nobjects) {
633  TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
636  void *begin = &(startbuf[0]);
637  void *end = &(endbuf[0]);
638  config->fCreateIterators( alternative, &begin, &end, newProxy);
639  // We can not get here with a split vector of pointer, so we can indeed assume
640  // that actions->fConfiguration != null.
641  buf.ApplySequence(*actions, begin, end);
642  if (begin != &(startbuf[0])) {
643  // assert(end != endbuf);
644  config->fDeleteTwoIterators(begin,end);
645  }
646  }
647  newProxy->Commit(alternative);
648  }
649  }
650 
652  {
653  // Collection was saved member-wise
654 
655  TConfigSTL *config = (TConfigSTL*)conf;
656 
658 
659  TClass *newClass = config->fNewClass;
660  TClass *oldClass = config->fOldClass;
661 
662  if( vers < 8 ) {
663  Error( "ReadSTLMemberWiseChangedClass", "Unfortunately, version %d of TStreamerInfo (used in %s) did not record enough information to convert a %s into a %s.",
664  vers, buf.GetParent() ? buf.GetParent()->GetName() : "memory/socket", oldClass->GetName(), newClass->GetName() );
665  } else {
666 
667  Version_t vClVersion = buf.ReadVersionForMemberWise( oldClass->GetCollectionProxy()->GetValueClass() );
668 
669  TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
670  TVirtualCollectionProxy *oldProxy = oldClass->GetCollectionProxy();
671 
672  int objectSize = newClass->Size();
673  char *obj = (char*)addr;
674  char *endobj = obj + conf->fLength*objectSize;
675 
676  for(; obj<endobj; obj+=objectSize) {
677  TVirtualCollectionProxy::TPushPop helper( newProxy, (char*)obj );
678  Int_t nobjects;
679  buf.ReadInt(nobjects);
680  void* alternative = newProxy->Allocate(nobjects,true);
681  if (nobjects) {
682  TActionSequence *actions = newProxy->GetConversionReadMemberWiseActions( oldProxy->GetValueClass(), vClVersion );
685  void *begin = &(startbuf[0]);
686  void *end = &(endbuf[0]);
687  config->fCreateIterators( alternative, &begin, &end, newProxy);
688  // We can not get here with a split vector of pointer, so we can indeed assume
689  // that actions->fConfiguration != null.
690  buf.ApplySequence(*actions, begin, end);
691  if (begin != &(startbuf[0])) {
692  // assert(end != endbuf);
693  config->fDeleteTwoIterators(begin,end);
694  }
695  }
696  newProxy->Commit(alternative);
697  }
698  }
699  }
700 
701 
702  INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseFastArray(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t /* vers */, UInt_t /* start */)
703  {
704  TConfigSTL *config = (TConfigSTL*)conf;
705  // Idea: This needs to be unrolled, it currently calls the TGenCollectionStreamer ....
706  buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
707  }
708  INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t /* vers */, UInt_t /* start */)
709  {
710  TConfigSTL *config = (TConfigSTL*)conf;
711  (*config->fStreamer)(buf,addr,conf->fLength);
712  }
714  {
715  // case of old TStreamerInfo
716 
717  TConfigSTL *config = (TConfigSTL*)conf;
718  // Backward compatibility. Some TStreamerElement's where without
719  // Streamer but were not removed from element list
720  if (config->fIsSTLBase || vers == 0) {
721  buf.SetBufferOffset(start); //there is no byte count
722  }
723  // Idea: This needs to be unrolled, it currently calls the TGenCollectionStreamer ....
724  buf.ReadFastArray(addr,config->fNewClass,conf->fLength,(TMemberStreamer*)0,config->fOldClass);
725  }
727  {
728  // case of old TStreamerInfo
729 
730  TConfigSTL *config = (TConfigSTL*)conf;
731  // Backward compatibility. Some TStreamerElement's where without
732  // Streamer but were not removed from element list
733  if (config->fIsSTLBase || vers == 0) {
734  buf.SetBufferOffset(start); //there is no byte count
735  }
736  (*config->fStreamer)(buf,addr,conf->fLength);
737  }
738 
739  template <void (*memberwise)(TBuffer&,void *,const TConfiguration*, Version_t),
740  void (*objectwise)(TBuffer&,void *,const TConfiguration*, Version_t, UInt_t)>
741  INLINE_TEMPLATE_ARGS Int_t ReadSTL(TBuffer &buf, void *addr, const TConfiguration *conf)
742  {
743  TConfigSTL *config = (TConfigSTL*)conf;
744  UInt_t start, count;
745  Version_t vers = buf.ReadVersion(&start, &count, config->fOldClass);
746  if ( vers & TBufferFile::kStreamedMemberWise ) {
747  memberwise(buf,((char*)addr)+config->fOffset,config, vers);
748  } else {
749  objectwise(buf,((char*)addr)+config->fOffset,config, vers, start);
750  }
751  buf.CheckByteCount(start,count,config->fTypeName);
752  return 0;
753  }
754 
755  template <typename From, typename To>
756  struct ConvertBasicType {
757  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
758  {
759  // Simple conversion from a 'From' on disk to a 'To' in memory.
760  From temp;
761  buf >> temp;
762  *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
763  return 0;
764  }
765  };
766 
767  template <typename To>
768  struct ConvertBasicType<BitsMarker,To> {
769  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
770  {
771  // Simple conversion from a 'From' on disk to a 'To' in memory
772  UInt_t temp;
773  buf >> temp;
774 
775  if ((temp & kIsReferenced) != 0) {
776  HandleReferencedTObject(buf,addr,config);
777  }
778 
779  *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
780  return 0;
781  }
782  };
783 
784  template <typename From, typename To>
785  struct ConvertBasicType<WithFactorMarker<From>,To> {
786  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
787  {
788  // Simple conversion from a 'From' on disk to a 'To' in memory.
789  TConfWithFactor *conf = (TConfWithFactor *)config;
790  From temp;
791  buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
792  *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
793  return 0;
794  }
795  };
796 
797  template <typename From, typename To>
798  struct ConvertBasicType<NoFactorMarker<From>,To> {
799  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *config)
800  {
801  // Simple conversion from a 'From' on disk to a 'To' in memory.
802  TConfNoFactor *conf = (TConfNoFactor *)config;
803  From temp;
804  buf.ReadWithNbits(&temp, conf->fNbits);
805  *(To*)( ((char*)addr) + config->fOffset ) = (To)temp;
806  return 0;
807  }
808  };
809 
810  class TConfigurationUseCache : public TConfiguration {
811  // Configuration object for the UseCache case.
812  public:
813  TConfiguredAction fAction;
814  Bool_t fNeedRepeat;
815 
816  TConfigurationUseCache(TVirtualStreamerInfo *info, TConfiguredAction &action, Bool_t repeat) :
817  TConfiguration(info,action.fConfiguration->fElemId,action.fConfiguration->fCompInfo,action.fConfiguration->fOffset),fAction(action),fNeedRepeat(repeat) {};
818  virtual void PrintDebug(TBuffer &b, void *addr) const
819  {
820  if (gDebug > 1) {
821  // Idea: We should print the name of the action function.
822  TStreamerInfo *info = (TStreamerInfo*)fInfo;
823  TStreamerElement *aElement = fCompInfo->fElem;
824  fprintf(stdout,"StreamerInfoAction, class:%s, name=%s, fType[%d]=%d,"
825  " %s, bufpos=%d, arr=%p, eoffset=%d, Redirect=%p\n",
826  info->GetClass()->GetName(),aElement->GetName(),fElemId,fCompInfo->fType,
827  aElement->ClassName(),b.Length(),addr, 0,b.PeekDataCache() ? b.PeekDataCache()->GetObjectAt(0) : 0);
828  }
829 
830  }
831  virtual ~TConfigurationUseCache() {};
832  virtual TConfiguration *Copy() {
833  TConfigurationUseCache *copy = new TConfigurationUseCache(*this);
834  fAction.fConfiguration = copy->fAction.fConfiguration->Copy(); // since the previous allocation did a 'move' of fAction we need to fix it.
835  return copy;
836  }
837  };
838 
839 
840  INLINE_TEMPLATE_ARGS Int_t UseCache(TBuffer &b, void *addr, const TConfiguration *conf)
841  {
842  TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
843 
844  Int_t bufpos = b.Length();
845  TVirtualArray *cached = b.PeekDataCache();
846  if (cached==0) {
847  TStreamerElement *aElement = conf->fCompInfo->fElem;
848  TStreamerInfo *info = (TStreamerInfo*)conf->fInfo;
849  Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
850  char *ptr = (char*)addr;
851  info->ReadBufferSkip(b,&ptr,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,1,0);
852  } else {
853  config->fAction(b, (*cached)[0]);
854  }
855  // Idea: Factor out this 'if' to a UseCacheRepeat function
856  if (config->fNeedRepeat) {
857  b.SetBufferOffset(bufpos);
858  }
859  return 0;
860  }
861 
862  INLINE_TEMPLATE_ARGS Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
863  {
864  TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
865  Int_t bufpos = b.Length();
866 
867  TVirtualArray *cached = b.PeekDataCache();
868  if (cached==0) {
869  TStreamerElement *aElement = config->fCompInfo->fElem;
870  TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
871  Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
872  char *ptr = (char*)start;
873  UInt_t n = (((void**)end)-((void**)start));
874  info->ReadBufferSkip(b,&ptr,config->fCompInfo,conf->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
875  } else {
876  TVectorLoopConfig cached_config( cached->fClass->Size(), /* read */ kTRUE );
877  void *cached_start = (*cached)[0];
878  void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
879  config->fAction(b,cached_start,cached_end,&cached_config);
880  }
881  // Idea: Factor out this 'if' to a UseCacheRepeat function
882  if (config->fNeedRepeat) {
883  b.SetBufferOffset(bufpos);
884  }
885  return 0;
886  }
887 
888  INLINE_TEMPLATE_ARGS Int_t UseCacheVectorLoop(TBuffer &b, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf)
889  {
890  TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
891 
892  Int_t bufpos = b.Length();
893  TVirtualArray *cached = b.PeekDataCache();
894  if (cached==0) {
895  TStreamerElement *aElement = config->fCompInfo->fElem;
896  TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
897  Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
898  char *ptr = (char*)start;
899  UInt_t n = (((char*)end)-((char*)start))/((TVectorLoopConfig*)loopconf)->fIncrement;
900  info->ReadBufferSkip(b,&ptr,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
901  } else {
902  TVectorLoopConfig cached_config( cached->fClass->Size(), /* read */ kTRUE );
903  void *cached_start = (*cached)[0];
904  void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
905  config->fAction(b,cached_start,cached_end,&cached_config);
906  }
907  // Idea: Factor out this 'if' to a UseCacheRepeat function
908  if (config->fNeedRepeat) {
909  b.SetBufferOffset(bufpos);
910  }
911  return 0;
912  }
913 
914  INLINE_TEMPLATE_ARGS Int_t UseCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
915  {
916  TConfigurationUseCache *config = (TConfigurationUseCache*)conf;
917 
918  Int_t bufpos = b.Length();
919  TVirtualArray *cached = b.PeekDataCache();
920  if (cached==0) {
921  TStreamerElement *aElement = config->fCompInfo->fElem;
922  TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
923 
924  TVirtualCollectionProxy *proxy = ((TGenericLoopConfig*)loopconfig)->fProxy;
925  Warning("ReadBuffer","Skipping %s::%s because the cache is missing.",info->GetName(),aElement->GetName());
926  UInt_t n = proxy->Size();
927  info->ReadBufferSkip(b, *proxy,config->fCompInfo,config->fCompInfo->fType+TStreamerInfo::kSkip,aElement,n,0);
928  } else {
929  TVectorLoopConfig cached_config( cached->fClass->Size(), /* read */ kTRUE );
930  void *cached_start = (*cached)[0];
931  void *cached_end = ((char*)cached_start) + cached->fSize * cached_config.fIncrement;
932  config->fAction(b,cached_start,cached_end,&cached_config);
933  }
934  // Idea: Factor out this 'if' to a UseCacheRepeat function
935  if (config->fNeedRepeat) {
936  b.SetBufferOffset(bufpos);
937  }
938  return 0;
939  }
940 
941  // Support for collections.
942 
943  Int_t ReadLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
944  {
945  Fatal("ApplySequence","The sequence of actions to read %s:%d member-wise was not initialized.",config->fInfo->GetName(),config->fInfo->GetClassVersion());
946  return 0;
947  }
948 
949  Int_t WriteLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
950  {
951  Fatal("ApplySequence","The sequence of actions to write %s:%d member-wise was not initialized.",config->fInfo->GetName(),config->fInfo->GetClassVersion());
952  return 0;
953  }
954 
956 
958  {
959  if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated) ) {
960  return kVectorLooper;
961  } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
962  || proxy.GetCollectionType() == ROOT::kSTLmultiset || proxy.GetCollectionType() == ROOT::kSTLunorderedmultiset
963  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap
964  || proxy.GetCollectionType() == ROOT::kSTLunorderedmap || proxy.GetCollectionType() == ROOT::kSTLunorderedmultimap
965  || proxy.GetCollectionType() == ROOT::kSTLbitset) {
966  return kAssociativeLooper;
967  } else {
968  return kGenericLooper;
969  }
970  }
971 
972  struct VectorLooper {
973 
974  template <typename T>
975  static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
976  {
977  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
978  iter = (char*)iter + config->fOffset;
979  end = (char*)end + config->fOffset;
980  for(; iter != end; iter = (char*)iter + incr ) {
981  T *x = (T*) ((char*) iter);
982  buf >> *x;
983  }
984  return 0;
985  }
986 
987  template <typename From, typename To>
988  struct ConvertBasicType {
989  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
990  {
991  // Simple conversion from a 'From' on disk to a 'To' in memory.
992  From temp;
993  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
994  iter = (char*)iter + config->fOffset;
995  end = (char*)end + config->fOffset;
996  for(; iter != end; iter = (char*)iter + incr ) {
997  buf >> temp;
998  *(To*)( ((char*)iter) ) = (To)temp;
999  }
1000  return 0;
1001  }
1002  };
1003 
1004  template <typename To>
1005  struct ConvertBasicType<BitsMarker,To> {
1006  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1007  {
1008  // Simple conversion from a 'From' on disk to a 'To' in memory.
1009  UInt_t temp;
1010  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1011  iter = (char*)iter + config->fOffset;
1012  end = (char*)end + config->fOffset;
1013  for(; iter != end; iter = (char*)iter + incr ) {
1014  buf >> temp;
1015 
1016  if ((temp & kIsReferenced) != 0) {
1017  HandleReferencedTObject(buf, (char*)iter - config->fOffset, config);
1018  }
1019 
1020  *(To*)( ((char*)iter) ) = (To)temp;
1021  }
1022  return 0;
1023  }
1024  };
1025 
1026  template <typename From, typename To>
1027  struct ConvertBasicType<WithFactorMarker<From>,To> {
1028  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1029  {
1030  // Simple conversion from a 'From' on disk to a 'To' in memory.
1031  TConfWithFactor *conf = (TConfWithFactor *)config;
1032  From temp;
1033  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1034  iter = (char*)iter + config->fOffset;
1035  end = (char*)end + config->fOffset;
1036  for(; iter != end; iter = (char*)iter + incr ) {
1037  buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
1038  *(To*)( ((char*)iter) ) = (To)temp;
1039  }
1040  return 0;
1041  }
1042  };
1043 
1044  template <typename From, typename To>
1045  struct ConvertBasicType<NoFactorMarker<From>,To> {
1046  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1047  {
1048  // Simple conversion from a 'From' on disk to a 'To' in memory.
1049  TConfNoFactor *conf = (TConfNoFactor *)config;
1050  From temp;
1051  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1052  iter = (char*)iter + config->fOffset;
1053  end = (char*)end + config->fOffset;
1054  for(; iter != end; iter = (char*)iter + incr ) {
1055  buf.ReadWithNbits(&temp, conf->fNbits);
1056  *(To*)( ((char*)iter) ) = (To)temp;
1057  }
1058  return 0;
1059  }
1060  };
1061 
1062  template <typename T>
1063  static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1064  {
1065  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1066  iter = (char*)iter + config->fOffset;
1067  end = (char*)end + config->fOffset;
1068  for(; iter != end; iter = (char*)iter + incr ) {
1069  T *x = (T*) ((char*) iter);
1070  buf << *x;
1071  }
1072  return 0;
1073  }
1074 
1075  template <Int_t (*iter_action)(TBuffer&,void *,const TConfiguration*)>
1076  static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconfig, const TConfiguration *config)
1077  {
1078  const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1079  //Idea: can we factor out the addition of fOffset
1080  // iter = (char*)iter + config->fOffset;
1081  for(void *iter = start; iter != end; iter = (char*)iter + incr ) {
1082  iter_action(buf, iter, config);
1083  }
1084  return 0;
1085  }
1086 
1087  static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1088  {
1089  // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
1090  // punt.
1091 
1092  UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1093  UInt_t n = (((char*)end)-((char*)start))/incr;
1094  char **arrptr = new char*[n];
1095  UInt_t i = 0;
1096  for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1097  arrptr[i] = (char*)iter;
1098  }
1099  ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
1100  delete [] arrptr;
1101 
1102  // // Idea: need to cache this result!
1103  // TStreamerInfo *info = (TStreamerInfo*)config->fInfo;
1104  // TStreamerElement *aElement = (TStreamerElement*)info->GetElem(config->fElemId);
1105  //
1106  // *Int_t clversion = ((TStreamerBase*)aElement)->Get BaseVersion();
1107  // *TClass *cle = aElement->GetNewBaseClass();
1108  // *(TSequence *actions = CreateReadMemberWiseActions( cle->GetStreamerInfo(clversion), ???? );
1109  //
1110  // TSequence *actions = CreateReadMemberWiseActions( ((TStreamerBase*)aElement)->GetBaseStreamerInfo(), ???? );
1111  //
1112  // actions->ReadBuffer(b,start,end);
1113  // delete actions;
1114 
1115  // const Int_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1116  // for(void *iter = start; iter != end; iter = (char*)iter + incr )
1117  // {
1118  // ((TStreamerInfo*)(((TStreamerBase*)aElement)->GetBaseStreamerInfo())->ReadBuffer(b,arr,-1,narr,ioffset,arrayMode);
1119  //
1120  // ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, (char**)&iter, config->fElemId, 1, config->fOffset, 1|2 );
1121  // }
1122  return 0;
1123  }
1124 
1125  static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1126  {
1127  // Well the implementation is non trivial. For now punt.
1128 
1129  UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1130  UInt_t n = (((char*)end)-((char*)start))/incr;
1131  char **arrptr = new char*[n];
1132  UInt_t i = 0;
1133  for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1134  arrptr[i] = (char*)iter;
1135  }
1136  ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
1137  delete [] arrptr;
1138  return 0;
1139  }
1140 
1141  static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1142  {
1143  // Well the implementation is non trivial. For now punt.
1144 
1145  UInt_t incr = ((TVectorLoopConfig*)loopconfig)->fIncrement;
1146  UInt_t n = (((char*)end)-((char*)start))/incr;
1147  char **arrptr = new char*[n];
1148  UInt_t i = 0;
1149  for(void *iter = start; iter != end; iter = (char*)iter + incr, ++i ) {
1150  arrptr[i] = (char*)iter;
1151  }
1152  ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, arrptr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, n, config->fOffset, 1|2 );
1153  delete [] arrptr;
1154  return 0;
1155  }
1156 
1157  template <typename T>
1158  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
1159  {
1160  // Collection of numbers. Memberwise or not, it is all the same.
1161 
1162  TConfigSTL *config = (TConfigSTL*)conf;
1163  UInt_t start, count;
1164  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1165 
1166  std::vector<T> *const vec = (std::vector<T>*)(((char*)addr)+config->fOffset);
1167  Int_t nvalues;
1168  buf.ReadInt(nvalues);
1169  vec->resize(nvalues);
1170 
1171 #ifdef R__VISUAL_CPLUSPLUS
1172  if (nvalues <= 0) {
1173  buf.CheckByteCount(start,count,config->fTypeName);
1174  return 0;
1175  }
1176 #endif
1177  T *begin = &(*vec->begin());
1178  buf.ReadFastArray(begin, nvalues);
1179 
1180  buf.CheckByteCount(start,count,config->fTypeName);
1181  return 0;
1182  }
1183 
1184  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBool(TBuffer &buf, void *addr, const TConfiguration *conf)
1185  {
1186  // Collection of numbers. Memberwise or not, it is all the same.
1187 
1188  TConfigSTL *config = (TConfigSTL*)conf;
1189  UInt_t start, count;
1190  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1191 
1192  std::vector<bool> *const vec = (std::vector<bool>*)(((char*)addr)+config->fOffset);
1193  Int_t nvalues;
1194  buf.ReadInt(nvalues);
1195  vec->resize(nvalues);
1196 
1197  bool *items = new bool[nvalues];
1198  buf.ReadFastArray(items, nvalues);
1199  for(Int_t i = 0 ; i < nvalues; ++i) {
1200  (*vec)[i] = items[i];
1201  }
1202  delete [] items;
1203 
1204  // We could avoid the call to ReadFastArray, and we could
1205  // the following, however this breaks TBufferXML ...
1206  // for(Int_t i = 0 ; i < nvalues; ++i) {
1207  // bool tmp; buf >> tmp;
1208  // (*vec)[i] = tmp;
1209  // }
1210 
1211  buf.CheckByteCount(start,count,config->fTypeName);
1212  return 0;
1213  }
1214 
1215  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
1216  {
1217  // Collection of numbers. Memberwise or not, it is all the same.
1218 
1219  TConfigSTL *config = (TConfigSTL*)conf;
1220  UInt_t start, count;
1221  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1222 
1223  std::vector<float> *const vec = (std::vector<float>*)(((char*)addr)+config->fOffset);
1224  Int_t nvalues;
1225  buf.ReadInt(nvalues);
1226  vec->resize(nvalues);
1227 
1228 #ifdef R__VISUAL_CPLUSPLUS
1229  if (nvalues <= 0) {
1230  buf.CheckByteCount(start,count,config->fTypeName);
1231  return 0;
1232  }
1233 #endif
1234  float *begin = &(*vec->begin());
1235  buf.ReadFastArrayFloat16(begin, nvalues);
1236 
1237  buf.CheckByteCount(start,count,config->fTypeName);
1238  return 0;
1239  }
1240 
1241  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
1242  {
1243  // Collection of numbers. Memberwise or not, it is all the same.
1244 
1245  TConfigSTL *config = (TConfigSTL*)conf;
1246  UInt_t start, count;
1247  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1248 
1249  std::vector<double> *const vec = (std::vector<double>*)(((char*)addr)+config->fOffset);
1250  Int_t nvalues;
1251  buf.ReadInt(nvalues);
1252  vec->resize(nvalues);
1253 
1254 #ifdef R__VISUAL_CPLUSPLUS
1255  if (nvalues <= 0) {
1256  buf.CheckByteCount(start,count,config->fTypeName);
1257  return 0;
1258  }
1259 #endif
1260  double *begin = &(*vec->begin());
1261  buf.ReadFastArrayDouble32(begin, nvalues);
1262 
1263  buf.CheckByteCount(start,count,config->fTypeName);
1264  return 0;
1265  }
1266 
1267  template <typename From, typename To>
1268  struct ConvertCollectionBasicType {
1269  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
1270  {
1271  // Collection of numbers. Memberwise or not, it is all the same.
1272 
1273  TConfigSTL *config = (TConfigSTL*)conf;
1274  UInt_t start, count;
1275  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1276 
1277  std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
1278  Int_t nvalues;
1279  buf.ReadInt(nvalues);
1280  vec->resize(nvalues);
1281 
1282  From *temp = new From[nvalues];
1283  buf.ReadFastArray(temp, nvalues);
1284  for(Int_t ind = 0; ind < nvalues; ++ind) {
1285  (*vec)[ind] = (To)temp[ind];
1286  }
1287  delete [] temp;
1288 
1289  buf.CheckByteCount(start,count,config->fTypeName);
1290  return 0;
1291  }
1292  };
1293 
1294  template <typename From, typename To>
1295  struct ConvertCollectionBasicType<NoFactorMarker<From>,To> {
1296  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
1297  {
1298  // Collection of numbers. Memberwise or not, it is all the same.
1299 
1300  TConfigSTL *config = (TConfigSTL*)conf;
1301  UInt_t start, count;
1302  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1303 
1304  std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
1305  Int_t nvalues;
1306  buf.ReadInt(nvalues);
1307  vec->resize(nvalues);
1308 
1309  From *temp = new From[nvalues];
1310  buf.ReadFastArrayWithNbits(temp, nvalues, 0);
1311  for(Int_t ind = 0; ind < nvalues; ++ind) {
1312  (*vec)[ind] = (To)temp[ind];
1313  }
1314  delete [] temp;
1315 
1316  buf.CheckByteCount(start,count,config->fTypeName);
1317  return 0;
1318  }
1319  };
1320 
1321  template <typename To>
1322  static INLINE_TEMPLATE_ARGS Int_t ConvertCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
1323  {
1324  // Collection of numbers. Memberwise or not, it is all the same.
1325 
1326  TConfigSTL *config = (TConfigSTL*)conf;
1327  UInt_t start, count;
1328  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1329 
1330  std::vector<To> *const vec = (std::vector<To>*)(((char*)addr)+config->fOffset);
1331  Int_t nvalues;
1332  buf.ReadInt(nvalues);
1333  vec->resize(nvalues);
1334 
1335  Double32_t *temp = new Double32_t[nvalues];
1336  buf.ReadFastArrayDouble32(temp, nvalues);
1337  for(Int_t ind = 0; ind < nvalues; ++ind) {
1338  (*vec)[ind] = (To)temp[ind];
1339  }
1340  delete [] temp;
1341 
1342  buf.CheckByteCount(start,count,config->fTypeName);
1343  return 0;
1344  }
1345 
1346  };
1347 
1348  struct VectorPtrLooper {
1349 
1350  template <typename T>
1351  static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1352  {
1353  const Int_t offset = config->fOffset;
1354 
1355  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1356  T *x = (T*)( ((char*) (*(void**)iter) ) + offset );
1357  buf >> *x;
1358  }
1359  return 0;
1360  }
1361 
1362  template <typename From, typename To>
1363  struct ConvertBasicType {
1364  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1365  {
1366  // Simple conversion from a 'From' on disk to a 'To' in memory.
1367  From temp;
1368  const Int_t offset = config->fOffset;
1369  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1370  buf >> temp;
1371  To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
1372  *x = (To)temp;
1373  }
1374  return 0;
1375  }
1376  };
1377 
1378  template <typename To>
1379  struct ConvertBasicType<BitsMarker,To> {
1380  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1381  {
1382  // Simple conversion from a 'From' on disk to a 'To' in memory.
1383  UInt_t temp;
1384  const Int_t offset = config->fOffset;
1385  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1386  buf >> temp;
1387 
1388  if ((temp & kIsReferenced) != 0) {
1389  HandleReferencedTObject(buf,*(void**)iter,config);
1390  }
1391 
1392  To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
1393  *x = (To)temp;
1394  }
1395  return 0;
1396  }
1397  };
1398 
1399  template <typename From, typename To>
1400  struct ConvertBasicType<WithFactorMarker<From>,To> {
1401  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1402  {
1403  // Simple conversion from a 'From' on disk to a 'To' in memory.
1404  TConfWithFactor *conf = (TConfWithFactor *)config;
1405  From temp;
1406  const Int_t offset = config->fOffset;
1407  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1408  buf.ReadWithFactor(&temp, conf->fFactor, conf->fXmin);
1409  To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
1410  *x = (To)temp;
1411  }
1412  return 0;
1413  }
1414  };
1415 
1416  template <typename From, typename To>
1417  struct ConvertBasicType<NoFactorMarker<From>,To> {
1418  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1419  {
1420  // Simple conversion from a 'From' on disk to a 'To' in memory.
1421  TConfNoFactor *conf = (TConfNoFactor *)config;
1422  From temp;
1423  const Int_t offset = config->fOffset;
1424  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1425  buf.ReadWithNbits(&temp, conf->fNbits);
1426  To *x = (To*)( ((char*) (*(void**)iter) ) + offset );
1427  *x = (To)temp;
1428  }
1429  return 0;
1430  }
1431  };
1432 
1433  template <typename T>
1434  static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1435  {
1436  const Int_t offset = config->fOffset;
1437 
1438  for(; iter != end; iter = (char*)iter + sizeof(void*) ) {
1439  T *x = (T*)( ((char*) (*(void**)iter) ) + offset );
1440  buf << *x;
1441  }
1442  return 0;
1443  }
1444 
1445  template <Int_t (*action)(TBuffer&,void *,const TConfiguration*)>
1446  static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
1447  {
1448  for(void *iter = start; iter != end; iter = (char*)iter + sizeof(void*) ) {
1449  action(buf, *(void**)iter, config);
1450  }
1451  return 0;
1452  }
1453 
1454  static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TConfiguration *config)
1455  {
1456  // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
1457  // punt.
1458 
1459  return GenericRead(buf,start,end,config);
1460  }
1461 
1462  static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1463  {
1464  Int_t n = ( ((void**)end) - ((void**)iter) );
1465  char **arr = (char**)iter;
1466  return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, arr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ n, config->fOffset, 1|2 );
1467  }
1468 
1469  static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *iter, const void *end, const TConfiguration *config)
1470  {
1471  Int_t n = ( ((void**)end) - ((void**)iter) );
1472  char **arr = (char**)iter;
1473  return ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, arr, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, n, config->fOffset, 1|2 );
1474  }
1475 
1476  };
1477 
1478  struct AssociativeLooper {
1479 
1480  template <typename T>
1481  static INLINE_TEMPLATE_ARGS void SimpleRead(TBuffer &buf, void *addr, Int_t nvalues)
1482  {
1483  buf.ReadFastArray((T*)addr, nvalues);
1484  }
1485 
1486  static INLINE_TEMPLATE_ARGS void SimpleReadFloat16(TBuffer &buf, void *addr, Int_t nvalues)
1487  {
1488  buf.ReadFastArrayFloat16((float*)addr, nvalues);
1489  }
1490 
1491  static INLINE_TEMPLATE_ARGS void SimpleReadDouble32(TBuffer &buf, void *addr, Int_t nvalues)
1492  {
1493  buf.ReadFastArrayDouble32((double*)addr, nvalues);
1494  }
1495 
1496  template <typename T,void (*action)(TBuffer&,void *,Int_t)>
1497  static INLINE_TEMPLATE_ARGS Int_t ReadNumericalCollection(TBuffer &buf, void *addr, const TConfiguration *conf)
1498  {
1499  // Collection of numbers. Memberwise or not, it is all the same.
1500 
1501  TConfigSTL *config = (TConfigSTL*)conf;
1502  UInt_t start, count;
1503  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1504 
1505  TClass *newClass = config->fNewClass;
1506  TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
1507  TVirtualCollectionProxy::TPushPop helper( newProxy, ((char*)addr)+config->fOffset );
1508 
1509  Int_t nvalues;
1510  buf.ReadInt(nvalues);
1511  void* alternative = newProxy->Allocate(nvalues,true);
1512  if (nvalues) {
1515  void *begin = &(startbuf[0]);
1516  void *end = &(endbuf[0]);
1517  config->fCreateIterators(alternative, &begin, &end, newProxy);
1518  // We can not get here with a split vector of pointer, so we can indeed assume
1519  // that actions->fConfiguration != null.
1520 
1521  action(buf,begin,nvalues);
1522 
1523  if (begin != &(startbuf[0])) {
1524  // assert(end != endbuf);
1525  config->fDeleteTwoIterators(begin,end);
1526  }
1527  }
1528  newProxy->Commit(alternative);
1529 
1530  buf.CheckByteCount(start,count,config->fTypeName);
1531  return 0;
1532  }
1533 
1534  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBool(TBuffer &buf, void *addr, const TConfiguration *conf)
1535  {
1536  return ReadNumericalCollection<bool,SimpleRead<bool> >(buf,addr,conf);
1537  }
1538 
1539  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
1540  {
1541  return ReadNumericalCollection<Float_t,SimpleReadFloat16 >(buf,addr,conf);
1542  }
1543 
1544  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
1545  {
1546  return ReadNumericalCollection<Double_t,SimpleReadDouble32 >(buf,addr,conf);
1547  }
1548 
1549  template <typename T>
1550  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
1551  {
1552  return ReadNumericalCollection<T,SimpleRead<T> >(buf,addr,conf);
1553  }
1554 
1555  template <typename From, typename To>
1556  struct ConvertRead {
1557  static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
1558  {
1559  From *temp = new From[nvalues];
1560  buf.ReadFastArray(temp, nvalues);
1561  To *vec = (To*)addr;
1562  for(Int_t ind = 0; ind < nvalues; ++ind) {
1563  vec[ind] = (To)temp[ind];
1564  }
1565  delete [] temp;
1566  }
1567  };
1568 
1569  template <typename From, typename To>
1570  struct ConvertRead<NoFactorMarker<From>,To> {
1571  static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
1572  {
1573  From *temp = new From[nvalues];
1574  buf.ReadFastArrayWithNbits(temp, nvalues,0);
1575  To *vec = (To*)addr;
1576  for(Int_t ind = 0; ind < nvalues; ++ind) {
1577  vec[ind] = (To)temp[ind];
1578  }
1579  delete [] temp;
1580  }
1581  };
1582 
1583  template <typename From, typename To>
1584  struct ConvertRead<WithFactorMarker<From>,To> {
1585  static INLINE_TEMPLATE_ARGS void Action(TBuffer &buf, void *addr, Int_t nvalues)
1586  {
1587  From *temp = new From[nvalues];
1588  double factor,min; // needs to be initialized.
1589  buf.ReadFastArrayWithFactor(temp, nvalues, factor, min);
1590  To *vec = (To*)addr;
1591  for(Int_t ind = 0; ind < nvalues; ++ind) {
1592  vec[ind] = (To)temp[ind];
1593  }
1594  delete [] temp;
1595  }
1596  };
1597 
1598  template <typename From, typename To>
1599  struct ConvertCollectionBasicType {
1600  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
1601  {
1602  return ReadNumericalCollection<To,ConvertRead<From,To>::Action >(buf,addr,conf);
1603  }
1604  };
1605 
1606  };
1607 
1608  struct GenericLooper {
1609 
1610  template <typename T>
1611  static INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1612  {
1613  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1614 
1615  Next_t next = loopconfig->fNext;
1616  const Int_t offset = config->fOffset;
1617 
1619  void *iter = loopconfig->fCopyIterator(iterator,start);
1620  void *addr;
1621  while( (addr = next(iter,end)) ) {
1622  T *x = (T*)( ((char*)addr) + offset );
1623  buf >> *x;
1624  }
1625  if (iter != &iterator[0]) {
1626  loopconfig->fDeleteIterator(iter);
1627  }
1628  return 0;
1629  }
1630 
1631  template <typename T>
1632  static INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1633  {
1634  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1635 
1636  Next_t next = loopconfig->fNext;
1637  const Int_t offset = config->fOffset;
1638 
1640  void *iter = loopconfig->fCopyIterator(iterator,start);
1641  void *addr;
1642  while( (addr = next(iter,end)) ) {
1643  T *x = (T*)( ((char*)addr) + offset );
1644  buf << *x;
1645  }
1646  if (iter != &iterator[0]) {
1647  loopconfig->fDeleteIterator(iter);
1648  }
1649  return 0;
1650  }
1651 
1652  template <Int_t (*iter_action)(TBuffer&,void *,const TConfiguration*)>
1653  static INLINE_TEMPLATE_ARGS Int_t ReadAction(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1654  {
1655  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1656 
1657  // const Int_t offset = config->fOffset;
1658  Next_t next = loopconfig->fNext;
1659 
1661  void *iter = loopconfig->fCopyIterator(&iterator,start);
1662  void *addr;
1663  while( (addr = next(iter,end)) ) {
1664  iter_action(buf, addr, config);
1665  }
1666  if (iter != &iterator[0]) {
1667  loopconfig->fDeleteIterator(iter);
1668  }
1669  return 0;
1670  }
1671 
1672  template <typename From, typename To>
1673  struct Generic {
1674  static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1675  {
1676  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1677 
1678  const Int_t offset = config->fOffset;
1679  Next_t next = loopconfig->fNext;
1680 
1682  void *iter = loopconfig->fCopyIterator(&iterator,start);
1683  void *addr;
1684  while( (addr = next(iter,end)) ) {
1685  To *x = (To*)( ((char*)addr) + offset );
1686  *x = (To)(*items);
1687  ++items;
1688  }
1689  if (iter != &iterator[0]) {
1690  loopconfig->fDeleteIterator(iter);
1691  }
1692  }
1693  };
1694 
1695  template <typename From, typename To>
1696  struct Numeric {
1697  static void ConvertAction(From *items, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration * /* config */)
1698  {
1699  // The difference with ConvertAction is that we can modify the start
1700  // iterator and skip the copy. We also never have an offset.
1701 
1702  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1703  Next_t next = loopconfig->fNext;
1704 
1705  void *iter = start;
1706  void *addr;
1707  while( (addr = next(iter,end)) ) {
1708  To *x = (To*)(addr);
1709  *x = (To)(*items);
1710  ++items;
1711  }
1712  }
1713  };
1714 
1715  template <typename From, typename To, template <typename F, typename T> class Converter = Generic >
1716  struct ConvertBasicType {
1717  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1718  {
1719  // Simple conversion from a 'From' on disk to a 'To' in memory.
1720 
1721  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1722  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1723  Int_t nvalues = proxy->Size();
1724 
1725  From *items = new From[nvalues];
1726  buf.ReadFastArray(items, nvalues);
1727  Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
1728  delete [] items;
1729  return 0;
1730  }
1731  };
1732 
1733  template <typename To>
1734  struct ConvertBasicType<BitsMarker, To, Generic> {
1735  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1736  {
1737  // Simple conversion from a 'From' on disk to a 'To' in memory.
1738 
1739  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1740  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1741  Int_t nvalues = proxy->Size();
1742 
1743  UInt_t *items_storage = new UInt_t[nvalues];
1744  UInt_t *items = items_storage;
1745 
1746  const Int_t offset = config->fOffset;
1747  Next_t next = loopconfig->fNext;
1748 
1750  void *iter = loopconfig->fCopyIterator(&iterator,start);
1751  void *addr;
1752  while( (addr = next(iter,end)) ) {
1753  buf >> (*items);
1754  if (((*items) & kIsReferenced) != 0) {
1755  HandleReferencedTObject(buf, addr, config);
1756  }
1757  To *x = (To*)( ((char*)addr) + offset );
1758  *x = (To)(*items);
1759  ++items;
1760  }
1761  if (iter != &iterator[0]) {
1762  loopconfig->fDeleteIterator(iter);
1763  }
1764 
1765  delete [] items_storage;
1766  return 0;
1767  }
1768  };
1769 
1770  template <typename From, typename To, template <typename F, typename T> class Converter >
1771  struct ConvertBasicType<WithFactorMarker<From>,To,Converter > {
1772  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1773  {
1774  // Simple conversion from a 'From' on disk to a 'To' in memory.
1775 
1776  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1777  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1778  Int_t nvalues = proxy->Size();
1779 
1780  TConfSTLWithFactor *conf = (TConfSTLWithFactor *)config;
1781 
1782  From *items = new From[nvalues];
1783  buf.ReadFastArrayWithFactor(items, nvalues, conf->fFactor, conf->fXmin);
1784  Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
1785  delete [] items;
1786  return 0;
1787  }
1788  };
1789 
1790  template <typename From, typename To, template <typename F, typename T> class Converter >
1791  struct ConvertBasicType<NoFactorMarker<From>,To,Converter > {
1792  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *config)
1793  {
1794  // Simple conversion from a 'From' on disk to a 'To' in memory.
1795 
1796  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1797  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1798  Int_t nvalues = proxy->Size();
1799 
1800  TConfSTLNoFactor *conf = (TConfSTLNoFactor *)config;
1801 
1802  From *items = new From[nvalues];
1803  buf.ReadFastArrayWithNbits(items, nvalues, conf->fNbits);
1804  Converter<From,To>::ConvertAction(items,start,end,loopconfig,config);
1805  delete [] items;
1806  return 0;
1807  }
1808  };
1809 
1810  static INLINE_TEMPLATE_ARGS Int_t ReadBase(TBuffer &buf, void *start, const void *end, const TLoopConfiguration * loopconfig, const TConfiguration *config)
1811  {
1812  // Well the implementation is non trivial since we do not have a proxy for the container of _only_ the base class. For now
1813  // punt.
1814 
1815  return GenericRead(buf,start,end,loopconfig, config);
1816  }
1817 
1818  static INLINE_TEMPLATE_ARGS Int_t GenericRead(TBuffer &buf, void *, const void *, const TLoopConfiguration * loopconf, const TConfiguration *config)
1819  {
1820  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1821  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1822  return ((TStreamerInfo*)config->fInfo)->ReadBuffer(buf, *proxy, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, /*narr*/ proxy->Size(), config->fOffset, 1|2 );
1823  }
1824 
1825  static INLINE_TEMPLATE_ARGS Int_t GenericWrite(TBuffer &buf, void *, const void *, const TLoopConfiguration * loopconf, const TConfiguration *config)
1826  {
1827  TGenericLoopConfig *loopconfig = (TGenericLoopConfig*)loopconf;
1828  TVirtualCollectionProxy *proxy = loopconfig->fProxy;
1829  return ((TStreamerInfo*)config->fInfo)->WriteBufferAux(buf, *proxy, &(config->fCompInfo), /*first*/ 0, /*last*/ 1, proxy->Size(), config->fOffset, 1|2 );
1830  }
1831 
1832  template <typename T>
1833  static INLINE_TEMPLATE_ARGS void SimpleRead(TBuffer &buf, void *addr)
1834  {
1835  buf >> *(T*)addr;
1836  }
1837 
1838  static INLINE_TEMPLATE_ARGS void SimpleReadFloat16(TBuffer &buf, void *addr)
1839  {
1840  buf.ReadWithNbits((float*)addr,12);
1841  }
1842 
1843  static INLINE_TEMPLATE_ARGS void SimpleReadDouble32(TBuffer &buf, void *addr)
1844  {
1845  //we read a float and convert it to double
1846  Float_t afloat;
1847  buf >> afloat;
1848  *(double*)addr = (Double_t)afloat;
1849  }
1850 
1851  template <typename ActionHolder>
1852  static INLINE_TEMPLATE_ARGS Int_t ReadNumericalCollection(TBuffer &buf, void *addr, const TConfiguration *conf)
1853  {
1854  // Collection of numbers. Memberwise or not, it is all the same.
1855 
1856  TConfigSTL *config = (TConfigSTL*)conf;
1857  UInt_t start, count;
1858  /* Version_t vers = */ buf.ReadVersion(&start, &count, config->fOldClass);
1859 
1860  TClass *newClass = config->fNewClass;
1861  TVirtualCollectionProxy *newProxy = newClass->GetCollectionProxy();
1862  TVirtualCollectionProxy::TPushPop helper( newProxy, ((char*)addr)+config->fOffset );
1863 
1864  Int_t nvalues;
1865  buf.ReadInt(nvalues);
1866  void* alternative = newProxy->Allocate(nvalues,true);
1867  if (nvalues) {
1870  void *begin = &(startbuf[0]);
1871  void *end = &(endbuf[0]);
1872  config->fCreateIterators(alternative, &begin, &end, newProxy);
1873  // We can not get here with a split vector of pointer, so we can indeed assume
1874  // that actions->fConfiguration != null.
1875 
1876  TGenericLoopConfig loopconf(newProxy, /* read */ kTRUE);
1877  ActionHolder::Action(buf,begin,end,&loopconf,config);
1878 
1879  if (begin != &(startbuf[0])) {
1880  // assert(end != endbuf);
1881  config->fDeleteTwoIterators(begin,end);
1882  }
1883  }
1884  newProxy->Commit(alternative);
1885 
1886  buf.CheckByteCount(start,count,config->fTypeName);
1887  return 0;
1888  }
1889 
1890  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBool(TBuffer &buf, void *addr, const TConfiguration *conf)
1891  {
1892  return ReadNumericalCollection<ConvertBasicType<bool,bool,Numeric > >(buf,addr,conf);
1893  }
1894 
1895  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionFloat16(TBuffer &buf, void *addr, const TConfiguration *conf)
1896  {
1897  return ReadNumericalCollection<ConvertBasicType<NoFactorMarker<float>,float,Numeric > >(buf,addr,conf);
1898  }
1899 
1900  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionDouble32(TBuffer &buf, void *addr, const TConfiguration *conf)
1901  {
1902  return ReadNumericalCollection<ConvertBasicType<float,double,Numeric > >(buf,addr,conf);
1903  // Could also use:
1904  // return ReadNumericalCollection<ConvertBasicType<NoFactorMarker<double>,double,Numeric > >(buf,addr,conf);
1905  }
1906 
1907  template <typename T>
1908  static INLINE_TEMPLATE_ARGS Int_t ReadCollectionBasicType(TBuffer &buf, void *addr, const TConfiguration *conf)
1909  {
1910  return ReadNumericalCollection<ConvertBasicType<T,T,Numeric > >(buf,addr,conf);
1911  }
1912 
1913  template <typename From, typename To>
1914  struct ConvertCollectionBasicType {
1915  static INLINE_TEMPLATE_ARGS Int_t Action(TBuffer &buf, void *addr, const TConfiguration *conf)
1916  {
1917  // return ReadNumericalCollection<To,ConvertRead<From,To>::Action >(buf,addr,conf);
1918  return ReadNumericalCollection<ConvertBasicType<From,To,Numeric > >(buf,addr,conf);
1919  }
1920  };
1921 
1922  };
1923 }
1924 
1925 template <typename Looper, typename From>
1926 static TConfiguredAction GetCollectionReadConvertAction(Int_t newtype, TConfiguration *conf)
1927 {
1928  switch (newtype) {
1929  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertBasicType<From,bool>::Action, conf ); break;
1930  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ConvertBasicType<From,char>::Action, conf ); break;
1931  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ConvertBasicType<From,short>::Action, conf ); break;
1932  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ConvertBasicType<From,Int_t>::Action, conf ); break;
1933  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ConvertBasicType<From,Long_t>::Action, conf ); break;
1934  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ConvertBasicType<From,Long64_t>::Action, conf ); break;
1935  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ConvertBasicType<From,float>::Action, conf ); break;
1936  case TStreamerInfo::kFloat16: return TConfiguredAction( Looper::template ConvertBasicType<From,float>::Action, conf ); break;
1937  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ConvertBasicType<From,double>::Action, conf ); break;
1938  case TStreamerInfo::kDouble32:return TConfiguredAction( Looper::template ConvertBasicType<From,double>::Action, conf ); break;
1939  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ConvertBasicType<From,UChar_t>::Action, conf ); break;
1940  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ConvertBasicType<From,UShort_t>::Action, conf ); break;
1941  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ConvertBasicType<From,UInt_t>::Action, conf ); break;
1942  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ConvertBasicType<From,ULong_t>::Action, conf ); break;
1943  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ConvertBasicType<From,ULong64_t>::Action, conf ); break;
1944  case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ConvertBasicType<From,UInt_t>::Action, conf ); break;
1945  default:
1946  return TConfiguredAction( Looper::GenericRead, conf );
1947  break;
1948  }
1949  R__ASSERT(0); // We should never be here
1950  return TConfiguredAction();
1951 }
1952 
1953 template <class Looper>
1955 {
1956  // If we ever support std::vector<Double32_t> fValues; //[...] we would get the info from the StreamerElement for fValues.
1957 
1958  switch (type) {
1959  // Read basic types.
1960  case TStreamerInfo::kBool: return TConfiguredAction( Looper::ReadCollectionBool, conf ); break;
1961  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<Char_t>, conf ); break;
1962  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<Short_t>,conf ); break;
1963  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<Int_t>, conf ); break;
1964  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long_t>, conf ); break;
1965  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long64_t>, conf ); break;
1966  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadCollectionBasicType<Float_t>, conf ); break;
1967  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadCollectionBasicType<Double_t>, conf ); break;
1968  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<UChar_t>, conf ); break;
1969  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<UShort_t>, conf ); break;
1970  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<UInt_t>, conf ); break;
1971  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong_t>, conf ); break;
1972  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong64_t>, conf ); break;
1973  case TStreamerInfo::kBits: Error("GetNumericCollectionReadAction","There is no support for kBits outside of a TObject."); break;
1974  case TStreamerInfo::kFloat16: {
1975  TConfigSTL *alternate = new TConfSTLNoFactor(conf,12);
1976  delete conf;
1977  return TConfiguredAction( Looper::ReadCollectionFloat16, alternate );
1978  // if (element->GetFactor() != 0) {
1979  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
1980  // } else {
1981  // Int_t nbits = (Int_t)element->GetXmin();
1982  // if (!nbits) nbits = 12;
1983  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
1984  // }
1985  break;
1986  }
1987  case TStreamerInfo::kDouble32: {
1988  TConfigSTL *alternate = new TConfSTLNoFactor(conf,0);
1989  delete conf;
1990  return TConfiguredAction( Looper::ReadCollectionDouble32, alternate );
1991  // if (element->GetFactor() != 0) {
1992  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
1993  // } else {
1994  // Int_t nbits = (Int_t)element->GetXmin();
1995  // if (!nbits) {
1996  // return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
1997  // } else {
1998  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
1999  // }
2000  // }
2001  break;
2002  }
2003  }
2004  Fatal("GetNumericCollectionReadAction","Is confused about %d",type);
2005  R__ASSERT(0); // We should never be here
2006  return TConfiguredAction();
2007 }
2008 
2009 template <typename Looper, typename From>
2010 static TConfiguredAction GetConvertCollectionReadActionFrom(Int_t newtype, TConfiguration *conf)
2011 {
2012  switch (newtype) {
2013  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,bool>::Action, conf ); break;
2014  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,char>::Action, conf ); break;
2015  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,short>::Action, conf ); break;
2016  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Int_t>::Action, conf ); break;
2017  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long_t>::Action, conf ); break;
2018  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long64_t>::Action, conf ); break;
2019  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2020  case TStreamerInfo::kFloat16: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2021  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2022  case TStreamerInfo::kDouble32:return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2023  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UChar_t>::Action, conf ); break;
2024  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UShort_t>::Action, conf ); break;
2025  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2026  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong_t>::Action, conf ); break;
2027  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong64_t>::Action, conf ); break;
2028  case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2029  default:
2030  break;
2031  }
2032  R__ASSERT(0); // We should never be here
2033  return TConfiguredAction();
2034 }
2035 
2036 template <typename Looper>
2037 static TConfiguredAction GetConvertCollectionReadAction(Int_t oldtype, Int_t newtype, TConfiguration *conf)
2038 {
2039  switch (oldtype) {
2040  case TStreamerInfo::kBool:
2041  return GetConvertCollectionReadActionFrom<Looper,Bool_t>(newtype, conf );
2042  break;
2043  case TStreamerInfo::kChar:
2044  return GetConvertCollectionReadActionFrom<Looper,Char_t>(newtype, conf );
2045  break;
2046  case TStreamerInfo::kShort:
2047  return GetConvertCollectionReadActionFrom<Looper,Short_t>(newtype, conf );
2048  break;
2049  case TStreamerInfo::kInt:
2050  return GetConvertCollectionReadActionFrom<Looper,Int_t>(newtype, conf );
2051  break;
2052  case TStreamerInfo::kLong:
2053  return GetConvertCollectionReadActionFrom<Looper,Long_t>(newtype, conf );
2054  break;
2056  return GetConvertCollectionReadActionFrom<Looper,Long64_t>(newtype, conf );
2057  break;
2058  case TStreamerInfo::kFloat:
2059  return GetConvertCollectionReadActionFrom<Looper,Float_t>( newtype, conf );
2060  break;
2062  return GetConvertCollectionReadActionFrom<Looper,Double_t>(newtype, conf );
2063  break;
2064  case TStreamerInfo::kUChar:
2065  return GetConvertCollectionReadActionFrom<Looper,UChar_t>(newtype, conf );
2066  break;
2068  return GetConvertCollectionReadActionFrom<Looper,UShort_t>(newtype, conf );
2069  break;
2070  case TStreamerInfo::kUInt:
2071  return GetConvertCollectionReadActionFrom<Looper,UInt_t>(newtype, conf );
2072  break;
2073  case TStreamerInfo::kULong:
2074  return GetConvertCollectionReadActionFrom<Looper,ULong_t>(newtype, conf );
2075  break;
2077  return GetConvertCollectionReadActionFrom<Looper,ULong64_t>(newtype, conf );
2078  break;
2080  return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Float16_t> >( newtype, conf );
2081  break;
2083  return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Double32_t> >( newtype, conf );
2084  break;
2085  case TStreamerInfo::kBits:
2086  Error("GetConvertCollectionReadAction","There is no support for kBits outside of a TObject.");
2087  break;
2088  default:
2089  break;
2090  }
2091  R__ASSERT(0); // We should never be here
2092  return TConfiguredAction();
2093 }
2094 
2095 template <class Looper>
2097 {
2098  switch (type) {
2099  // Read basic types.
2100  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ReadBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2101  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2102  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadBasicType<Short_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2103  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2104  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2105  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2106  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2107  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2108  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2109  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2110  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2111  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2112  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadBasicType<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2113  case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ReadAction<TStreamerInfoActions::ReadBasicType<BitsMarker> > , new TBitsConfiguration(info,i,compinfo,offset) ); break;
2114  case TStreamerInfo::kFloat16: {
2115  if (element->GetFactor() != 0) {
2116  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2117  } else {
2118  Int_t nbits = (Int_t)element->GetXmin();
2119  if (!nbits) nbits = 12;
2120  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2121  }
2122  break;
2123  }
2124  case TStreamerInfo::kDouble32: {
2125  if (element->GetFactor() != 0) {
2126  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2127  } else {
2128  Int_t nbits = (Int_t)element->GetXmin();
2129  if (!nbits) {
2130  return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double>::Action >, new TConfiguration(info,i,compinfo,offset) );
2131  } else {
2132  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2133  }
2134  }
2135  break;
2136  }
2137  case TStreamerInfo::kTNamed: return TConfiguredAction( Looper::template ReadAction<ReadTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
2138  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2139  // Streamer alltogether.
2140  case TStreamerInfo::kTObject: return TConfiguredAction( Looper::template ReadAction<ReadTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
2141  case TStreamerInfo::kTString: return TConfiguredAction( Looper::template ReadAction<ReadTString >, new TConfiguration(info,i,compinfo,offset) ); break;
2145  case TStreamerInfo::kSTL: return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) ); break;
2146  case TStreamerInfo::kBase: return TConfiguredAction( Looper::ReadBase, new TGenericConfiguration(info,i,compinfo) ); break;
2147 
2148  // Conversions.
2150  return GetCollectionReadConvertAction<Looper,Bool_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2151  break;
2153  return GetCollectionReadConvertAction<Looper,Char_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2154  break;
2156  return GetCollectionReadConvertAction<Looper,Short_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2157  break;
2159  return GetCollectionReadConvertAction<Looper,Int_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2160  break;
2162  return GetCollectionReadConvertAction<Looper,Long_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2163  break;
2165  return GetCollectionReadConvertAction<Looper,Long64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2166  break;
2168  return GetCollectionReadConvertAction<Looper,Float_t>( element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2169  break;
2171  return GetCollectionReadConvertAction<Looper,Double_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2172  break;
2174  return GetCollectionReadConvertAction<Looper,UChar_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2175  break;
2177  return GetCollectionReadConvertAction<Looper,UShort_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2178  break;
2180  return GetCollectionReadConvertAction<Looper,UInt_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2181  break;
2183  return GetCollectionReadConvertAction<Looper,ULong_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2184  break;
2186  return GetCollectionReadConvertAction<Looper,ULong64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2187  break;
2189  return GetCollectionReadConvertAction<Looper,BitsMarker>(element->GetNewType(), new TBitsConfiguration(info,i,compinfo,offset) );
2190  break;
2192  if (element->GetFactor() != 0) {
2193  return GetCollectionReadConvertAction<Looper,WithFactorMarker<float> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2194  } else {
2195  Int_t nbits = (Int_t)element->GetXmin();
2196  if (!nbits) nbits = 12;
2197  return GetCollectionReadConvertAction<Looper,NoFactorMarker<float> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2198  }
2199  break;
2200  }
2202  if (element->GetFactor() != 0) {
2203  return GetCollectionReadConvertAction<Looper,WithFactorMarker<double> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2204  } else {
2205  Int_t nbits = (Int_t)element->GetXmin();
2206  if (!nbits) {
2207  return GetCollectionReadConvertAction<Looper,Float_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2208  } else {
2209  return GetCollectionReadConvertAction<Looper,NoFactorMarker<double> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2210  }
2211  }
2212  break;
2213  }
2214  default:
2215  return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) );
2216  break;
2217  }
2218  R__ASSERT(0); // We should never be here
2219  return TConfiguredAction();
2220 }
2221 
2222 template <class Looper>
2224  switch (type) {
2225  // read basic types
2226  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template WriteBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2227  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template WriteBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2228  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template WriteBasicType<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2229  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template WriteBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2230  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template WriteBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2231  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template WriteBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2232  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template WriteBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2233  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template WriteBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2234  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template WriteBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2235  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template WriteBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2236  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template WriteBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2237  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template WriteBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2238  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template WriteBasicType<ULong64_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2239  // the simple type missing are kBits and kCounter.
2240  default:
2241  return TConfiguredAction( Looper::GenericWrite, new TConfiguration(info,i,compinfo,0 /* 0 because we call the legacy code */) );
2242  }
2243  R__ASSERT(0); // We should never be here
2244  return TConfiguredAction();
2245 }
2246 
2247 
2248 ////////////////////////////////////////////////////////////////////////////////
2249 /// loop on the TStreamerElement list
2250 /// regroup members with same type
2251 /// Store predigested information into local arrays. This saves a huge amount
2252 /// of time compared to an explicit iteration on all elements.
2253 
2255 {
2256  if (IsCompiled()) {
2257  //Error("Compile","can only be called once; this first call generates both the optimized and memberwise actions.");
2258  return;
2259  }
2261 
2262  // fprintf(stderr,"Running Compile for %s %d %d req=%d,%d\n",GetName(),fClassVersion,fOptimized,CanOptimize(),TestBit(kCannotOptimize));
2263 
2264  // if (IsCompiled() && (!fOptimized || (CanOptimize() && !TestBit(kCannotOptimize)))) return;
2265  fOptimized = kFALSE;
2266  fNdata = 0;
2267  fNfulldata = 0;
2268 
2269  TObjArray* infos = (TObjArray*) gROOT->GetListOfStreamerInfo();
2270  if (fNumber >= infos->GetSize()) {
2271  infos->AddAtAndExpand(this, fNumber);
2272  } else {
2273  if (!infos->At(fNumber)) {
2274  infos->AddAt(this, fNumber);
2275  }
2276  }
2277 
2278  assert(fComp == 0 && fCompFull == 0 && fCompOpt == 0);
2279 
2280 
2281  Int_t ndata = fElements->GetEntries();
2282 
2283 
2284  if (fReadObjectWise) fReadObjectWise->fActions.clear();
2285  else fReadObjectWise = new TStreamerInfoActions::TActionSequence(this,ndata);
2286 
2287  if (fWriteObjectWise) fWriteObjectWise->fActions.clear();
2288  else fWriteObjectWise = new TStreamerInfoActions::TActionSequence(this,ndata);
2289 
2290  if (fReadMemberWise) fReadMemberWise->fActions.clear();
2291  else fReadMemberWise = new TStreamerInfoActions::TActionSequence(this,ndata);
2292 
2293  if (fWriteMemberWise) fWriteMemberWise->fActions.clear();
2294  else fWriteMemberWise = new TStreamerInfoActions::TActionSequence(this,ndata);
2295 
2296  if (fReadMemberWiseVecPtr) fReadMemberWiseVecPtr->fActions.clear();
2297  else fReadMemberWiseVecPtr = new TStreamerInfoActions::TActionSequence(this,ndata);
2298 
2299  if (fWriteMemberWiseVecPtr) fWriteMemberWiseVecPtr->fActions.clear();
2300  else fWriteMemberWiseVecPtr = new TStreamerInfoActions::TActionSequence(this,ndata);
2301 
2302  if (!ndata) {
2303  // This may be the case for empty classes (e.g., TAtt3D).
2304  // We still need to properly set the size of emulated classes (i.e. add the virtual table)
2305  if (fClass->TestBit(TClass::kIsEmulation) && fNVirtualInfoLoc!=0) {
2306  fSize = sizeof(TStreamerInfo*);
2307  }
2308  fComp = new TCompInfo[1];
2309  fCompFull = new TCompInfo*[1];
2310  fCompOpt = new TCompInfo*[1];
2311  fCompOpt[0] = fCompFull[0] = &(fComp[0]);
2312  SetIsCompiled();
2313  return;
2314  }
2315 
2316  // At most half of the elements can be used to hold optimized versions.
2317  // We use the bottom to hold the optimized-into elements and the non-optimized elements
2318  // and the top to hold the original copy of the optimized out elements.
2319  fNslots = ndata + ndata/2 + 1;
2320  Int_t optiOut = 0;
2321 
2322  fComp = new TCompInfo[fNslots];
2323  fCompFull = new TCompInfo*[ndata];
2324  fCompOpt = new TCompInfo*[ndata];
2325 
2326  TStreamerElement* element;
2327  TStreamerElement* previous = 0;
2328  Int_t keep = -1;
2329  Int_t i;
2330 
2331  if (!CanOptimize()) {
2332  SetBit(kCannotOptimize);
2333  }
2334 
2335  Bool_t isOptimized = kFALSE;
2336  Bool_t previousOptimized = kFALSE;
2337 
2338  for (i = 0; i < ndata; ++i) {
2339  element = (TStreamerElement*) fElements->At(i);
2340  if (!element) {
2341  break;
2342  }
2343 
2344  Int_t asize = element->GetSize();
2345  if (element->GetArrayLength()) {
2346  asize /= element->GetArrayLength();
2347  }
2348  fComp[fNdata].fType = element->GetType();
2349  fComp[fNdata].fNewType = element->GetNewType();
2350  fComp[fNdata].fOffset = element->GetOffset();
2351  fComp[fNdata].fLength = element->GetArrayLength();
2352  fComp[fNdata].fElem = element;
2353  fComp[fNdata].fMethod = element->GetMethod();
2354  fComp[fNdata].fClass = element->GetClassPointer();
2355  fComp[fNdata].fNewClass = element->GetNewClass();
2356  fComp[fNdata].fClassName = TString(element->GetTypeName()).Strip(TString::kTrailing, '*');
2357  fComp[fNdata].fStreamer = element->GetStreamer();
2358 
2359  // try to group consecutive members of the same type
2360  if (!TestBit(kCannotOptimize)
2361  && (keep >= 0)
2362  && (element->GetType() >=0)
2363  && (element->GetType() < 10)
2364  && (fComp[fNdata].fType == fComp[fNdata].fNewType)
2365  && (fComp[keep].fMethod == 0)
2366  && (element->GetType() > 0)
2367  && (element->GetArrayDim() == 0)
2368  && (fComp[keep].fType < kObject)
2369  && (fComp[keep].fType != kCharStar) /* do not optimize char* */
2370  && (element->GetType() == (fComp[keep].fType%kRegrouped))
2371  && ((element->GetOffset()-fComp[keep].fOffset) == (fComp[keep].fLength)*asize)
2372  && ((fOldVersion<6) || !previous || /* In version of TStreamerInfo less than 6, the Double32_t were merged even if their annotation (aka factor) were different */
2373  ((element->GetFactor() == previous->GetFactor())
2374  && (element->GetXmin() == previous->GetXmin())
2375  && (element->GetXmax() == previous->GetXmax())
2376  )
2377  )
2380  // kWholeObject and kDoNotDelete do not apply to numerical elements.
2381  )
2382  {
2383  if (!previousOptimized) {
2384  // The element was not yet optimized we first need to copy it into
2385  // the set of original copies.
2386  fComp[fNslots - (++optiOut) ] = fComp[keep]; // Copy the optimized out elements.
2387  fCompFull[fNfulldata-1] = &(fComp[fNslots - optiOut]); // Reset the pointer in the full list.
2388  }
2389  fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the optimized out elements.
2390  fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
2391 
2392  R__ASSERT( keep < (fNslots - optiOut) );
2393 
2394  if (fComp[keep].fLength == 0) {
2395  fComp[keep].fLength++;
2396  }
2397  fComp[keep].fLength++;
2398  fComp[keep].fType = element->GetType() + kRegrouped;
2399  isOptimized = kTRUE;
2400  previousOptimized = kTRUE;
2401  } else if (element->GetType() < 0) {
2402 
2403  // -- Deal with an ignored TObject base class.
2404  // Note: The only allowed negative value here is -1,
2405  // and signifies that Build() has found a TObject
2406  // base class and TClass::IgnoreTObjectStreamer() was
2407  // called. In this case the compiled version of the
2408  // elements omits the TObject base class element,
2409  // which has to be compensated for by TTree::Bronch()
2410  // when it is making branches for a split object.
2411  fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the 'ignored' element.
2412  fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
2413  keep = -1;
2414  previousOptimized = kFALSE;
2415 
2416  } else {
2417  if (fComp[fNdata].fNewType != fComp[fNdata].fType) {
2418  if (fComp[fNdata].fNewType > 0) {
2419  if ( (fComp[fNdata].fNewType == kObjectp || fComp[fNdata].fNewType == kAnyp
2420  || fComp[fNdata].fNewType == kObject || fComp[fNdata].fNewType == kAny
2421  || fComp[fNdata].fNewType == kTObject || fComp[fNdata].fNewType == kTNamed || fComp[fNdata].fNewType == kTString)
2422  && (fComp[fNdata].fType == kObjectp || fComp[fNdata].fType == kAnyp
2423  || fComp[fNdata].fType == kObject || fComp[fNdata].fType == kAny
2424  || fComp[fNdata].fType == kTObject || fComp[fNdata].fType == kTNamed || fComp[fNdata].fType == kTString )
2425  ) {
2426  fComp[fNdata].fType = fComp[fNdata].fNewType;
2427  } else if (fComp[fNdata].fType != kCounter) {
2428  fComp[fNdata].fType += kConv;
2429  }
2430  } else {
2431  if (fComp[fNdata].fType == kCounter) {
2432  Warning("Compile", "Counter %s should not be skipped from class %s", element->GetName(), GetName());
2433  }
2434  fComp[fNdata].fType += kSkip;
2435  }
2436  }
2437  fCompOpt[fNdata] = &(fComp[fNdata]);
2438  fCompFull[fNfulldata] = &(fComp[fNdata]);
2439 
2440  R__ASSERT( fNdata < (fNslots - optiOut) );
2441 
2442  keep = fNdata;
2443  if (fComp[keep].fLength == 0) {
2444  fComp[keep].fLength = 1;
2445  }
2446  fNdata++;
2447  previousOptimized = kFALSE;
2448  }
2449  // The test 'fMethod[keep] == 0' fails to detect a variable size array
2450  // if the counter happens to have an offset of zero, so let's explicitly
2451  // prevent for here.
2452  if (element->HasCounter()) keep = -1;
2453  ++fNfulldata;
2454  previous = element;
2455  }
2456 
2457  for (i = 0; i < fNdata; ++i) {
2458  if (!fCompOpt[i]->fElem || fCompOpt[i]->fElem->GetType()< 0) {
2459  continue;
2460  }
2461  AddReadAction(fReadObjectWise, i, fCompOpt[i]);
2462  AddWriteAction(fWriteObjectWise, i, fCompOpt[i]);
2463  }
2464  for (i = 0; i < fNfulldata; ++i) {
2465  if (!fCompFull[i]->fElem || fCompFull[i]->fElem->GetType()< 0) {
2466  continue;
2467  }
2468  AddReadAction(fReadMemberWise, i, fCompFull[i]);
2469  AddWriteAction(fWriteMemberWise, i, fCompFull[i]);
2470  AddReadMemberWiseVecPtrAction(fReadMemberWiseVecPtr, i, fCompFull[i]);
2471  AddWriteMemberWiseVecPtrAction(fWriteMemberWiseVecPtr, i, fCompFull[i]);
2472  }
2473  ComputeSize();
2474 
2475  fOptimized = isOptimized;
2476  SetIsCompiled();
2477 
2478  if (gDebug > 0) {
2479  ls();
2480  }
2481 }
2482 
2483 template <typename From>
2484 static void AddReadConvertAction(TStreamerInfoActions::TActionSequence *sequence, Int_t newtype, TConfiguration *conf)
2485 {
2486  switch (newtype) {
2487  case TStreamerInfo::kBool: sequence->AddAction( ConvertBasicType<From,bool>::Action, conf ); break;
2488  case TStreamerInfo::kChar: sequence->AddAction( ConvertBasicType<From,char>::Action, conf ); break;
2489  case TStreamerInfo::kShort: sequence->AddAction( ConvertBasicType<From,short>::Action, conf ); break;
2490  case TStreamerInfo::kInt: sequence->AddAction( ConvertBasicType<From,Int_t>::Action, conf ); break;
2491  case TStreamerInfo::kLong: sequence->AddAction( ConvertBasicType<From,Long_t>::Action,conf ); break;
2492  case TStreamerInfo::kLong64: sequence->AddAction( ConvertBasicType<From,Long64_t>::Action, conf ); break;
2493  case TStreamerInfo::kFloat: sequence->AddAction( ConvertBasicType<From,float>::Action, conf ); break;
2494  case TStreamerInfo::kFloat16: sequence->AddAction( ConvertBasicType<From,float>::Action, conf ); break;
2495  case TStreamerInfo::kDouble: sequence->AddAction( ConvertBasicType<From,double>::Action, conf ); break;
2496  case TStreamerInfo::kDouble32:sequence->AddAction( ConvertBasicType<From,double>::Action, conf ); break;
2497  case TStreamerInfo::kUChar: sequence->AddAction( ConvertBasicType<From,UChar_t>::Action, conf ); break;
2498  case TStreamerInfo::kUShort: sequence->AddAction( ConvertBasicType<From,UShort_t>::Action, conf ); break;
2499  case TStreamerInfo::kUInt: sequence->AddAction( ConvertBasicType<From,UInt_t>::Action, conf ); break;
2500  case TStreamerInfo::kULong: sequence->AddAction( ConvertBasicType<From,ULong_t>::Action, conf ); break;
2501  case TStreamerInfo::kULong64: sequence->AddAction( ConvertBasicType<From,ULong64_t>::Action,conf ); break;
2502  case TStreamerInfo::kBits: sequence->AddAction( ConvertBasicType<From,UInt_t>::Action, conf ); break;
2503  }
2504 }
2505 
2506 ////////////////////////////////////////////////////////////////////////////////
2507 /// Add a read action for the given element.
2508 
2510 {
2511  TStreamerElement *element = compinfo->fElem;
2512 
2513  if (element->TestBit(TStreamerElement::kWrite)) return;
2514 
2515  switch (compinfo->fType) {
2516  // read basic types
2517  case TStreamerInfo::kBool: readSequence->AddAction( ReadBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2518  case TStreamerInfo::kChar: readSequence->AddAction( ReadBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2519  case TStreamerInfo::kShort: readSequence->AddAction( ReadBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2520  case TStreamerInfo::kInt: readSequence->AddAction( ReadBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2521  case TStreamerInfo::kLong: readSequence->AddAction( ReadBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2522  case TStreamerInfo::kLong64: readSequence->AddAction( ReadBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2523  case TStreamerInfo::kFloat: readSequence->AddAction( ReadBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2524  case TStreamerInfo::kDouble: readSequence->AddAction( ReadBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2525  case TStreamerInfo::kUChar: readSequence->AddAction( ReadBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2526  case TStreamerInfo::kUShort: readSequence->AddAction( ReadBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2527  case TStreamerInfo::kUInt: readSequence->AddAction( ReadBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2528  case TStreamerInfo::kULong: readSequence->AddAction( ReadBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2529  case TStreamerInfo::kULong64: readSequence->AddAction( ReadBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2530  case TStreamerInfo::kBits: readSequence->AddAction( ReadBasicType<BitsMarker>, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2531  case TStreamerInfo::kFloat16: {
2532  if (element->GetFactor() != 0) {
2533  readSequence->AddAction( ReadBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2534  } else {
2535  Int_t nbits = (Int_t)element->GetXmin();
2536  if (!nbits) nbits = 12;
2537  readSequence->AddAction( ReadBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2538  }
2539  break;
2540  }
2541  case TStreamerInfo::kDouble32: {
2542  if (element->GetFactor() != 0) {
2543  readSequence->AddAction( ReadBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2544  } else {
2545  Int_t nbits = (Int_t)element->GetXmin();
2546  if (!nbits) {
2547  readSequence->AddAction( ConvertBasicType<float,double>::Action, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2548  } else {
2549  readSequence->AddAction( ReadBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2550  }
2551  }
2552  break;
2553  }
2554  case TStreamerInfo::kTNamed: readSequence->AddAction( ReadTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2555  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2556  // Streamer alltogether.
2557  case TStreamerInfo::kTObject: readSequence->AddAction( ReadTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2558  case TStreamerInfo::kTString: readSequence->AddAction( ReadTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2559  case TStreamerInfo::kSTL: {
2560  TClass *newClass = element->GetNewClass();
2561  TClass *oldClass = element->GetClassPointer();
2562  Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
2563 
2564  if (element->GetArrayLength() <= 1) {
2565  if (fOldVersion<3){ // case of old TStreamerInfo
2566  if (newClass && newClass != oldClass) {
2567  if (element->GetStreamer()) {
2568  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2569  } else {
2570  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2571  }
2572  } else {
2573  if (element->GetStreamer()) {
2574  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2575  } else {
2576  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2577  }
2578  }
2579  } else {
2580  if (newClass && newClass != oldClass) {
2581  if (element->GetStreamer()) {
2582  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2583  } else {
2584  if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
2585  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2586  } else {
2587  switch (SelectLooper(*newClass->GetCollectionProxy())) {
2588  case kVectorLooper:
2589  readSequence->AddAction(GetConvertCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2590  break;
2591  case kAssociativeLooper:
2592  readSequence->AddAction(GetConvertCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2593  break;
2594  case kVectorPtrLooper:
2595  case kGenericLooper:
2596  default:
2597  // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
2598  readSequence->AddAction(GetConvertCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2599  break;
2600  }
2601  }
2602  }
2603  } else {
2604  if (element->GetStreamer()) {
2605  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2606  } else {
2607  if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
2608  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2609  } else {
2610  switch (SelectLooper(*oldClass->GetCollectionProxy())) {
2611  case kVectorLooper:
2612  readSequence->AddAction(GetNumericCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2613  break;
2614  case kAssociativeLooper:
2615  readSequence->AddAction(GetNumericCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2616  break;
2617  case kVectorPtrLooper:
2618  case kGenericLooper:
2619  default:
2620  // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
2621  readSequence->AddAction(GetNumericCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2622  break;
2623  }
2624  }
2625  }
2626  }
2627  }
2628  } else {
2629  if (fOldVersion<3){ // case of old TStreamerInfo
2630  if (newClass && newClass != oldClass) {
2631  if (element->GetStreamer()) {
2632  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2633  } else {
2634  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2635  }
2636  } else {
2637  if (element->GetStreamer()) {
2638  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2639  } else {
2640  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2641  }
2642  }
2643  } else {
2644  if (newClass && newClass != oldClass) {
2645  if (element->GetStreamer()) {
2646  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2647  } else {
2648  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2649  }
2650  } else {
2651  if (element->GetStreamer()) {
2652  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2653  } else {
2654  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2655  }
2656  }
2657  }
2658  }
2659  break;
2660  }
2661 
2663  AddReadConvertAction<Bool_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2664  break;
2666  AddReadConvertAction<Char_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2667  break;
2669  AddReadConvertAction<Short_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2670  break;
2672  AddReadConvertAction<Int_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2673  break;
2675  AddReadConvertAction<Long_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2676  break;
2678  AddReadConvertAction<Long64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2679  break;
2681  AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2682  break;
2684  AddReadConvertAction<Double_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2685  break;
2687  AddReadConvertAction<UChar_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2688  break;
2690  AddReadConvertAction<UShort_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2691  break;
2693  AddReadConvertAction<UInt_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2694  break;
2696  AddReadConvertAction<ULong_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2697  break;
2699  AddReadConvertAction<ULong64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2700  break;
2702  AddReadConvertAction<BitsMarker>(readSequence, compinfo->fNewType, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) );
2703  break;
2705  if (element->GetFactor() != 0) {
2706  AddReadConvertAction<WithFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2707  } else {
2708  Int_t nbits = (Int_t)element->GetXmin();
2709  if (!nbits) nbits = 12;
2710  AddReadConvertAction<NoFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2711  }
2712  break;
2713  }
2715  if (element->GetFactor() != 0) {
2716  AddReadConvertAction<WithFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2717  } else {
2718  Int_t nbits = (Int_t)element->GetXmin();
2719  if (!nbits) {
2720  AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2721  } else {
2722  AddReadConvertAction<NoFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2723  }
2724  }
2725  break;
2726  }
2727  default:
2728  readSequence->AddAction( GenericReadAction, new TGenericConfiguration(this,i,compinfo) );
2729  break;
2730  }
2731  if (element->TestBit(TStreamerElement::kCache)) {
2732  TConfiguredAction action( readSequence->fActions.back() ); // Action is moved, we must pop it next.
2733  readSequence->fActions.pop_back();
2734  readSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2735  }
2736 }
2737 
2738 ////////////////////////////////////////////////////////////////////////////////
2739 /// Add a read action for the given element.
2740 /// This is for streaming via a TClonesArray (or a vector of pointers of this type).
2741 
2743 {
2744  TStreamerElement *element = compinfo->fElem;
2745 
2746  if (element->TestBit(TStreamerElement::kWrite)) return;
2747 
2748  if (element->TestBit(TStreamerElement::kCache)) {
2749  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2750  readSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2751  } else {
2752  readSequence->AddAction( GetCollectionReadAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2753  }
2754 }
2755 
2756 ////////////////////////////////////////////////////////////////////////////////
2757 
2759 {
2760  TStreamerElement *element = compinfo->fElem;
2761  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
2762  // Skip element cached for reading purposes.
2763  return;
2764  }
2765  if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
2766  // Skip artificial element used for reading purposes.
2767  return;
2768  }
2769  switch (compinfo->fType) {
2770  // write basic types
2771  case TStreamerInfo::kBool: writeSequence->AddAction( WriteBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2772  case TStreamerInfo::kChar: writeSequence->AddAction( WriteBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2773  case TStreamerInfo::kShort: writeSequence->AddAction( WriteBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2774  case TStreamerInfo::kInt: writeSequence->AddAction( WriteBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2775  case TStreamerInfo::kLong: writeSequence->AddAction( WriteBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2776  case TStreamerInfo::kLong64: writeSequence->AddAction( WriteBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2777  case TStreamerInfo::kFloat: writeSequence->AddAction( WriteBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2778  case TStreamerInfo::kDouble: writeSequence->AddAction( WriteBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2779  case TStreamerInfo::kUChar: writeSequence->AddAction( WriteBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2780  case TStreamerInfo::kUShort: writeSequence->AddAction( WriteBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2781  case TStreamerInfo::kUInt: writeSequence->AddAction( WriteBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2782  case TStreamerInfo::kULong: writeSequence->AddAction( WriteBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2783  case TStreamerInfo::kULong64: writeSequence->AddAction( WriteBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2784  // case TStreamerInfo::kBits: writeSequence->AddAction( WriteBasicType<BitsMarker>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2785  /*case TStreamerInfo::kFloat16: {
2786  if (element->GetFactor() != 0) {
2787  writeSequence->AddAction( WriteBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2788  } else {
2789  Int_t nbits = (Int_t)element->GetXmin();
2790  if (!nbits) nbits = 12;
2791  writeSequence->AddAction( WriteBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2792  }
2793  break;
2794  } */
2795  /*case TStreamerInfo::kDouble32: {
2796  if (element->GetFactor() != 0) {
2797  writeSequence->AddAction( WriteBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2798  } else {
2799  Int_t nbits = (Int_t)element->GetXmin();
2800  if (!nbits) {
2801  writeSequence->AddAction( ConvertBasicType<float,double>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2802  } else {
2803  writeSequence->AddAction( WriteBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2804  }
2805  }
2806  break;
2807  } */
2808  //case TStreamerInfo::kTNamed: writeSequence->AddAction( WriteTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2809  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2810  // Streamer alltogether.
2811  //case TStreamerInfo::kTObject: writeSequence->AddAction( WriteTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2812  //case TStreamerInfo::kTString: writeSequence->AddAction( WriteTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2813  /*case TStreamerInfo::kSTL: {
2814  TClass *newClass = element->GetNewClass();
2815  TClass *oldClass = element->GetClassPointer();
2816  Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
2817 
2818  if (element->GetArrayLength() <= 1) {
2819  if (newClass && newClass != oldClass) {
2820  if (element->GetStreamer()) {
2821  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2822  } else {
2823  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2824  }
2825  } else {
2826  if (element->GetStreamer()) {
2827  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2828  } else {
2829  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2830  }
2831  }
2832  } else {
2833  if (newClass && newClass != oldClass) {
2834  if (element->GetStreamer()) {
2835  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2836  } else {
2837  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2838  }
2839  } else {
2840  if (element->GetStreamer()) {
2841  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2842  } else {
2843  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2844  }
2845  }
2846  }
2847  break;
2848  } */
2849  default:
2850  writeSequence->AddAction( GenericWriteAction, new TGenericConfiguration(this,i,compinfo) );
2851  break;
2852  }
2853 #if defined(CDJ_NO_COMPILE)
2854  if (element->TestBit(TStreamerElement::kCache)) {
2855  TConfiguredAction action( writeSequence->fActions.back() ); // Action is moved, we must pop it next.
2856  writeSequence->fActions.pop_back();
2857  writeSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2858  }
2859 #endif
2860 }
2861 
2862 ////////////////////////////////////////////////////////////////////////////////
2863 /// This is for streaming via a TClonesArray (or a vector of pointers of this type).
2864 
2866 {
2867  TStreamerElement *element = compinfo->fElem;
2868  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
2869  // Skip element cached for reading purposes.
2870  return;
2871  }
2872  if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
2873  // Skip artificial element used for reading purposes.
2874  return;
2875  }
2876 
2877 #if defined(CDJ_NO_COMPILE)
2878  if (element->TestBit(TStreamerElement::kCache)) {
2879  TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2880  writeSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2881  } else {
2882  writeSequence->Addaction( GetCollectionWriteAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2883  }
2884 #else
2885  writeSequence->AddAction( VectorPtrLooper::GenericWrite, new TGenericConfiguration(this,i,compinfo) );
2886 #endif
2887 
2888 }
2889 
2890 ////////////////////////////////////////////////////////////////////////////////
2891 /// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
2892 
2894 {
2895  if (info == 0) {
2896  return new TStreamerInfoActions::TActionSequence(0,0);
2897  }
2898 
2899  TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
2900 
2901  UInt_t ndata = info->GetElements()->GetEntries();
2903  if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated) )
2904  {
2905  if (proxy.HasPointers()) {
2906  // Instead of the creating a new one let's copy the one from the StreamerInfo.
2907  delete sequence;
2908 
2909  sequence = sinfo->GetReadMemberWiseActions(kTRUE)->CreateCopy();
2910 
2911  return sequence;
2912  }
2913 
2914  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
2915  Long_t increment = proxy.GetIncrement();
2916  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kTRUE);
2917  } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
2918  || proxy.GetCollectionType() == ROOT::kSTLmultiset || proxy.GetCollectionType() == ROOT::kSTLunorderedmultiset
2919  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap
2920  || proxy.GetCollectionType() == ROOT::kSTLunorderedmap || proxy.GetCollectionType() == ROOT::kSTLunorderedmultimap)
2921  {
2922  Long_t increment = proxy.GetIncrement();
2923  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kTRUE);
2924  // sequence->fLoopConfig = new TAssocLoopConfig(proxy);
2925  } else {
2926  sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kTRUE);
2927  }
2928  for (UInt_t i = 0; i < ndata; ++i) {
2929  TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
2930  if (!element) {
2931  break;
2932  }
2933  if (element->GetType() < 0) {
2934  // -- Skip an ignored TObject base class.
2935  // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
2936  // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
2937  // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
2938  // when it is making branches for a split object.
2939  continue;
2940  }
2941  if (element->TestBit(TStreamerElement::kWrite)) {
2942  // Skip element that only for writing.
2943  continue;
2944  }
2945  TStreamerBase *baseEl = dynamic_cast<TStreamerBase*>(element);
2946  if (baseEl) {
2947  if (baseEl->GetErrorMessage()[0]) {
2948  // There was a problem with the checksum, the user likely did not
2949  // increment the version number of the derived class when the
2950  // base class changed. Since we will be member wise streaming
2951  // this class, let's warn the user that something is wrong.
2952  ::Warning("CreateReadMemberWiseActions","%s",
2953  baseEl->GetErrorMessage());
2954  }
2955  }
2956 
2957  TStreamerInfo::TCompInfo_t *compinfo = sinfo->fCompFull[i];
2958 
2959  Int_t asize = element->GetSize();
2960  if (element->GetArrayLength()) {
2961  asize /= element->GetArrayLength();
2962  }
2963  Int_t oldType = element->GetType();
2964  Int_t newType = element->GetNewType();
2965 
2966  Int_t offset = element->GetOffset();
2967  if (newType != oldType) {
2968  if (newType > 0) {
2969  if (oldType != TVirtualStreamerInfo::kCounter) {
2970  oldType += TVirtualStreamerInfo::kConv;
2971  }
2972  } else {
2973  oldType += TVirtualStreamerInfo::kSkip;
2974  }
2975  }
2976  switch (SelectLooper(proxy)) {
2977  case kAssociativeLooper:
2978 // } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
2979 // || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
2980 // sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
2981  case kVectorLooper:
2982  case kVectorPtrLooper:
2983  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
2984  if (element->TestBit(TStreamerElement::kCache)) {
2985  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
2986  sequence->AddAction( UseCacheVectorLoop, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
2987  } else {
2988  sequence->AddAction( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
2989  }
2990  break;
2991  case kGenericLooper:
2992  default:
2993  // The usual collection case.
2994  if (element->TestBit(TStreamerElement::kCache)) {
2995  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
2996  sequence->AddAction( UseCacheGenericCollection, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
2997  } else {
2998  sequence->AddAction( GetCollectionReadAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
2999  }
3000  break;
3001  }
3002  }
3003  return sequence;
3004 }
3005 
3006 ////////////////////////////////////////////////////////////////////////////////
3007 /// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
3008 
3010 {
3011  if (info == 0) {
3012  return new TStreamerInfoActions::TActionSequence(0,0);
3013  }
3014 
3015  UInt_t ndata = info->GetElements()->GetEntries();
3016  TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
3018 
3019  if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated) )
3020  {
3021  if (proxy.HasPointers()) {
3022  // Instead of the creating a new one let's copy the one from the StreamerInfo.
3023  delete sequence;
3024 
3025  sequence = sinfo->GetWriteMemberWiseActions(kTRUE)->CreateCopy();
3026 
3027  return sequence;
3028  }
3029 
3030  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3031  Long_t increment = proxy.GetIncrement();
3032  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kFALSE);
3033  /*} else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3034  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)
3035  {
3036  Long_t increment = proxy.GetIncrement();
3037  sequence->fLoopConfig = new TVectorLoopConfig(increment);
3038  // sequence->fLoopConfig = new TAssocLoopConfig(proxy); */
3039  } else {
3040  sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kFALSE);
3041  }
3042  for (UInt_t i = 0; i < ndata; ++i) {
3043  TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
3044  if (!element) {
3045  break;
3046  }
3047  if (element->GetType() < 0) {
3048  // -- Skip an ignored TObject base class.
3049  // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
3050  // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
3051  // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
3052  // when it is making branches for a split object.
3053  continue;
3054  }
3055  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
3056  // Skip element cached for reading purposes.
3057  continue;
3058  }
3060  // Skip artificial element used for reading purposes.
3061  continue;
3062  }
3063  TStreamerInfo::TCompInfo *compinfo = sinfo->fCompFull[i];
3064  Int_t asize = element->GetSize();
3065  if (element->GetArrayLength()) {
3066  asize /= element->GetArrayLength();
3067  }
3068  Int_t oldType = element->GetType();
3069  Int_t offset = element->GetOffset();
3070 #if defined(CDJ_NO_COMPILE)
3071  Int_t newType = element->GetNewType();
3072 
3073  if (newType != oldType) {
3074  if (newType > 0) {
3075  if (oldType != TVirtualStreamerInfo::kCounter) {
3076  oldType += TVirtualStreamerInfo::kConv;
3077  }
3078  } else {
3079  oldType += TVirtualStreamerInfo::kSkip;
3080  }
3081  }
3082  if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated)
3083  /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3084  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) */ )
3085  {
3086 
3087  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3088  if (element->TestBit(TStreamerElement::kCache)) {
3089  TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3090  sequence->AddAction( UseCacheVectorLoop, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
3091  } else {
3092  sequence->AddAction(GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
3093  }
3094 
3095  // } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3096  // || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
3097  // sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
3098  } else {
3099  // The usual collection case.
3100  if (element->TestBit(TStreamerElement::kCache)) {
3101  TConfiguredAction action( GetWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3102  sequence->AddAction( UseCacheGenericCollection, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
3103  } else {
3104  switch (oldType) {
3105  // read basic types
3106  case TVirtualStreamerInfo::kBool: sequence->AddAction( WriteBasicTypeGenericLoop<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3107  case TVirtualStreamerInfo::kChar: sequence->AddAction( WriteBasicTypeGenericLoop<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3108  case TVirtualStreamerInfo::kShort: sequence->AddAction( WriteBasicTypeGenericLoop<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3109  case TVirtualStreamerInfo::kInt: sequence->AddAction( WriteBasicTypeGenericLoop<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3110  case TVirtualStreamerInfo::kLong: sequence->AddAction( WriteBasicTypeGenericLoop<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3111  case TVirtualStreamerInfo::kLong64: sequence->AddAction( WriteBasicTypeGenericLoop<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3112  case TVirtualStreamerInfo::kFloat: sequence->AddAction( WriteBasicTypeGenericLoop<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3113  case TVirtualStreamerInfo::kDouble: sequence->AddAction( WriteBasicTypeGenericLoop<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3114  case TVirtualStreamerInfo::kUChar: sequence->AddAction( WriteBasicTypeGenericLoop<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3115  case TVirtualStreamerInfo::kUShort: sequence->AddAction( WriteBasicTypeGenericLoop<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3116  case TVirtualStreamerInfo::kUInt: sequence->AddAction( WriteBasicTypeGenericLoop<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3117  case TVirtualStreamerInfo::kULong: sequence->AddAction( WriteBasicTypeGenericLoop<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3118  case TVirtualStreamerInfo::kULong64: sequence->AddAction( WriteBasicTypeGenericLoop<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3119  // case TVirtualStreamerInfo::kBits: sequence->AddAction( WriteBasicTypeGenericLoop<BitsMarker>, new TConfiguration(info,i,compinfo,offset) ); break;
3121  if (element->GetFactor() != 0) {
3122  sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
3123  } else {
3124  Int_t nbits = (Int_t)element->GetXmin();
3125  if (!nbits) nbits = 12;
3126  sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
3127  }
3128  break;
3129  }
3131  if (element->GetFactor() != 0) {
3132  sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
3133  } else {
3134  Int_t nbits = (Int_t)element->GetXmin();
3135  if (!nbits) {
3136  sequence->AddAction( GenericLooper<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
3137  } else {
3138  sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
3139  }
3140  }
3141  break;
3142  }
3143  case TVirtualStreamerInfo::kTNamed: sequence->AddAction( GenericLooper<WriteTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
3144  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
3145  // Streamer alltogether.
3146  case TVirtualStreamerInfo::kTObject: sequence->AddAction( GenericLooper<WriteTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
3147  case TVirtualStreamerInfo::kTString: sequence->AddAction( GenericLooper<WriteTString >, new TConfiguration(info,i,compinfo,offset) ); break;
3148  default:
3149  sequence->AddAction( GenericCollectionWriteAction, new TConfigSTL(info,i,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
3150  break;
3151  }
3152  }
3153  }
3154 #else
3155  if ( (proxy.GetCollectionType() == ROOT::kSTLvector) || (proxy.GetProperties() & TVirtualCollectionProxy::kIsEmulated)
3156  /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3157  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)*/ )
3158  {
3159  sequence->AddAction( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3160  } else {
3161  // NOTE: TBranch::FillLeavesCollection[Member] is not yet ready to handle the sequence
3162  // as it does not create/use a TStaging as expected ... but then again it might
3163  // not be the right things to expect ...
3164  // sequence->AddAction( GetCollectionWriteAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
3165  sequence->AddAction( GenericLooper::GenericWrite, new TConfigSTL(info,i,compinfo,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
3166  }
3167 #endif
3168  }
3169  return sequence;
3170 }
3172 {
3173  // Add the (potentially negative) delta to all the configuration's offset. This is used by
3174  // TBranchElement in the case of split sub-object.
3175 
3176  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3177  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3178  iter != end;
3179  ++iter)
3180  {
3181  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3182  iter->fConfiguration->AddToOffset(delta);
3183  }
3184 }
3185 
3187 {
3188  // Create a copy of this sequence.
3189 
3190  TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,fActions.size());
3191 
3192  sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
3193 
3194  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3195  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3196  iter != end;
3197  ++iter)
3198  {
3199  TConfiguration *conf = iter->fConfiguration->Copy();
3200  sequence->AddAction( iter->fAction, conf );
3201  }
3202  return sequence;
3203 }
3204 
3206 {
3207  // Create a sequence containing the subset of the action corresponding to the SteamerElement whose ids is contained in the vector.
3208  // 'offset' is the location of this 'class' within the object (address) that will be passed to ReadBuffer when using this sequence.
3209 
3210  TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,element_ids.size());
3211 
3212  sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
3213 
3214  for(UInt_t id = 0; id < element_ids.size(); ++id) {
3215  if ( element_ids[id] < 0 ) {
3216  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3217  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3218  iter != end;
3219  ++iter)
3220  {
3221  TConfiguration *conf = iter->fConfiguration->Copy();
3222  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3223  conf->AddToOffset(offset);
3224  sequence->AddAction( iter->fAction, conf );
3225  }
3226  } else {
3227  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3228  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3229  iter != end;
3230  ++iter) {
3231  if ( iter->fConfiguration->fElemId == (UInt_t)element_ids[id] ) {
3232  TConfiguration *conf = iter->fConfiguration->Copy();
3233  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3234  conf->AddToOffset(offset);
3235  sequence->AddAction( iter->fAction, conf );
3236  }
3237  }
3238  }
3239  }
3240  return sequence;
3241 }
3242 
3243 #if !defined(R__WIN32) && !defined(_AIX)
3244 
3245 #include <dlfcn.h>
3246 
3247 #endif
3248 
3249 typedef void (*voidfunc)();
3250 static const char *R__GetSymbolName(voidfunc func)
3251 {
3252 #if defined(R__WIN32) || defined(__CYGWIN__) || defined(_AIX)
3253  return "not available on this platform";
3254 #if 0
3255  MEMORY_BASIC_INFORMATION mbi;
3256  if (!VirtualQuery (func, &mbi, sizeof (mbi)))
3257  {
3258  return 0;
3259  }
3260 
3261  HMODULE hMod = (HMODULE) mbi.AllocationBase;
3262  static char moduleName[MAX_PATH];
3263 
3264  if (!GetModuleFileNameA (hMod, moduleName, sizeof (moduleName)))
3265  {
3266  return 0;
3267  }
3268  return moduleName;
3269 #endif
3270 #else
3271  Dl_info info;
3272  if (dladdr((void*)func,&info)==0) {
3273  // Not in a known share library, let's give up
3274  return "name not found";
3275  } else {
3276  //fprintf(stdout,"Found address in %s\n",info.dli_fname);
3277  return info.dli_sname;
3278  }
3279 #endif
3280 }
3281 
3283 {
3284  // Add the (potentially negative) delta to all the configuration's offset. This is used by
3285  // TTBranchElement in the case of split sub-object.
3286  // If opt contains 'func', also print the (mangled) name of the function that will be executed.
3287 
3288  if (fLoopConfig) {
3289  fLoopConfig->Print();
3290  }
3291  TStreamerInfoActions::ActionContainer_t::const_iterator end = fActions.end();
3292  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = fActions.begin();
3293  iter != end;
3294  ++iter)
3295  {
3296  iter->fConfiguration->Print();
3297  if (strstr(opt,"func")) {
3298  printf("StreamerInfoAction func: %s\n",R__GetSymbolName((voidfunc)iter->fAction));
3299  }
3300  }
3301 }
3302 
3303 
const int ndata
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
std::string GetName(const std::string &scope_name)
Definition: Cppyy.cxx:145
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:88
virtual Int_t GetCollectionType() const =0
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:382
double read(const std::string &file_name)
reading
INLINE_TEMPLATE_ARGS Int_t ReadBasicType_WithFactor(TBuffer &buf, void *addr, const TConfiguration *config)
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...
Definition: TProcessID.cxx:344
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.
An array of TObjects.
Definition: TObjArray.h:37
float xmin
Definition: THbookFile.cxx:93
virtual void * Allocate(UInt_t n, Bool_t forceDelete)=0
TVirtualStreamerInfo * fInfo
TStreamerInfo form which the action is derived.
static void AddReadConvertAction(TStreamerInfoActions::TActionSequence *sequence, Int_t newtype, TConfiguration *conf)
static TConfiguredAction GetConvertCollectionReadActionFrom(Int_t newtype, TConfiguration *conf)
virtual TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Int_t version)=0
virtual Int_t GetProperties() const
void AddReadMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read action for the given element.
short Version_t
Definition: RtypesCore.h:61
void Fatal(const char *location, const char *msgfmt,...)
INLINE_TEMPLATE_ARGS Int_t ReadSTL(TBuffer &buf, void *addr, const TConfiguration *conf)
TLoopConfiguration * fLoopConfig
If this is a bundle of memberwise streaming action, this configures the looping.
void AddReadAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read action for the given element.
float Float_t
Definition: RtypesCore.h:53
Equal to TDataType&#39;s kchar.
static void * CopyIterator(void *dest, const void *source)
virtual TStreamerInfoActions::TActionSequence * GetConversionReadMemberWiseActions(TClass *oldClass, Int_t version)=0
const char Option_t
Definition: RtypesCore.h:62
virtual TClass * GetValueClass() const =0
void AddAction(action_t action, TConfiguration *conf)
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:231
static void * Next(void *iter, const void *end)
double T(double x)
Definition: ChebyshevPol.h:34
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:40
T ReadBuffer(TBufferFile *buf)
One of the template functions used to read objects from messages.
Definition: MPSendRecv.h:157
virtual void PrintDebug(TBuffer &buffer, void *object) const
unsigned short UShort_t
Definition: RtypesCore.h:36
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:159
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
static TConfiguredAction GetNumericCollectionReadAction(Int_t type, TConfigSTL *conf)
INLINE_TEMPLATE_ARGS Int_t ReadBasicType< BitsMarker >(TBuffer &buf, void *addr, const TConfiguration *config)
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
Definition: TClass.cxx:4360
INLINE_TEMPLATE_ARGS Int_t ReadBasicType_NoFactor(TBuffer &buf, void *addr, const TConfiguration *config)
TMemberStreamer * GetStreamer() const
Return the local streamer object.
virtual void Commit(void *)=0
INLINE_TEMPLATE_ARGS Int_t UseCacheVectorLoop(TBuffer &b, void *start, const void *end, const TLoopConfiguration *loopconf, const TConfiguration *conf)
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
INLINE_TEMPLATE_ARGS Int_t ReadTObject(TBuffer &buf, void *addr, const TConfiguration *config)
virtual TClass * GetCollectionClass() const
#define R__ASSERT(e)
Definition: TError.h:96
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:375
void AddWriteAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo)
UInt_t fElemId
Identifier of the TStreamerElement.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2814
Int_t GetArrayLength() const
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
Cache the value in memory than is not part of the object but is accessible via a SchemaRule.
virtual UShort_t GetPidOffset() const =0
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).
virtual DeleteIterator_t GetFunctionDeleteIterator(Bool_t read=kTRUE)=0
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
Int_t GetArrayDim() const
INLINE_TEMPLATE_ARGS Int_t ReadTString(TBuffer &buf, void *addr, const TConfiguration *config)
virtual EDataType GetType() const =0
void GetSequenceType(TString &type) const
Fill type with the string representation of sequence information including &#39;cached&#39;,&#39;repeat&#39;,&#39;write&#39; or &#39;nodelete&#39;.
void *(* CopyIterator_t)(void *dest, const void *source)
Float_t delta
INLINE_TEMPLATE_ARGS void ReadArraySTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
TCompInfo ** fCompFull
![fElements->GetEntries()]
static TActionSequence * CreateReadMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by &#39;...
virtual void ReadInt(Int_t &i)=0
TVirtualCollectionProxy::Next_t Next_t
TActionSequence * CreateSubSequence(const std::vector< Int_t > &element_ids, size_t offset)
Int_t Length() const
Definition: TBuffer.h:94
void(* DeleteIterator_t)(void *iter)
INLINE_TEMPLATE_ARGS void ReadSTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
static TConfiguredAction GetCollectionReadAction(TVirtualStreamerInfo *info, TStreamerElement *element, Int_t type, UInt_t i, TStreamerInfo::TCompInfo_t *compinfo, Int_t offset)
virtual void ReadWithNbits(Float_t *ptr, Int_t nbits)=0
virtual Int_t GetClassVersion() const =0
INLINE_TEMPLATE_ARGS Int_t WriteBasicType(TBuffer &buf, void *addr, const TConfiguration *config)
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:135
char * GetObjectAt(UInt_t ind) const
Definition: TVirtualArray.h:38
Double_t x[n]
Definition: legend1.C:17
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition: TBuffer.cxx:313
void Class()
Definition: Class.C:29
void(* voidfunc)()
virtual void Copy(TObject &object) const
Copy this to obj.
Definition: TObject.cxx:60
Int_t WriteLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
virtual TLoopConfiguration * Copy()=0
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:69
double Double32_t
Definition: RtypesCore.h:56
Base class of the Configurations for the member wise looping routines.
Int_t ReadLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
void Error(const char *location, const char *msgfmt,...)
virtual DeleteTwoIterators_t GetFunctionDeleteTwoIterators(Bool_t read=kTRUE)=0
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
Int_t GenericWriteAction(TBuffer &buf, void *addr, const TConfiguration *config)
ESelectLooper SelectLooper(TVirtualCollectionProxy &proxy)
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:698
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseFastArray(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t, UInt_t)
virtual Version_t ReadVersionForMemberWise(const TClass *cl=0)=0
static TConfiguredAction GetCollectionReadConvertAction(Int_t newtype, TConfiguration *conf)
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:222
TClass * GetClass() const
Wrapper around an object and giving indirect access to its content even if the object is not of a cla...
Definition: TVirtualArray.h:26
virtual void ReadFastArrayDouble32(Double_t *d, Int_t n, TStreamerElement *ele=0)=0
static TConfiguredAction GetCollectionWriteAction(TVirtualStreamerInfo *info, TStreamerElement *, Int_t type, UInt_t i, TStreamerInfo::TCompInfo_t *compinfo, Int_t offset)
virtual Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object)=0
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
Int_t fOffset
Offset within the object.
virtual void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue)=0
virtual Bool_t HasPointers() const =0
Double_t GetXmin() const
static TActionSequence * CreateWriteMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by &#39;...
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=0)=0
unsigned int UInt_t
Definition: RtypesCore.h:42
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5348
virtual TVirtualArray * PeekDataCache() const
Return the &#39;current&#39; data cache area from the list of area to be used for temporarily store &#39;missing&#39;...
Definition: TBuffer.cxx:340
virtual void ReadWithFactor(Float_t *ptr, Double_t factor, Double_t minvalue)=0
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition: TString.cxx:2488
TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Bool_t forCollection)
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t, UInt_t)
void Warning(const char *location, const char *msgfmt,...)
INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *addr, const TConfiguration *config)
static const Int_t fgIteratorArenaSize
virtual void ReadFastArray(Bool_t *b, Int_t n)=0
INLINE_TEMPLATE_ARGS Int_t UseCacheGenericCollection(TBuffer &b, void *, const void *, const TLoopConfiguration *loopconfig, const TConfiguration *conf)
virtual void AddAt(TObject *obj, Int_t idx)
Add object at position ids.
Definition: TObjArray.cxx:239
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseStreamerV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
const Bool_t kFALSE
Definition: RtypesCore.h:92
PyObject * fType
TStreamerElement * fElem
Not Owned.
Definition: TStreamerInfo.h:55
virtual ULong_t GetIncrement() const =0
long Long_t
Definition: RtypesCore.h:50
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
Double_t GetXmax() const
void HandleReferencedTObject(TBuffer &buf, void *addr, const TConfiguration *config)
void Copy(void *source, void *dest)
void Print(Option_t *="") const
This method must be overridden when a class wants to print itself.
#define INLINE_TEMPLATE_ARGS
void Print(std::ostream &os, const OptionType &opt)
virtual void ReadFastArrayWithNbits(Float_t *ptr, Int_t n, Int_t nbits)=0
double Double_t
Definition: RtypesCore.h:55
virtual TObjArray * GetElements() const =0
INLINE_TEMPLATE_ARGS Int_t UseCache(TBuffer &b, void *addr, const TConfiguration *conf)
Double_t GetFactor() const
int type
Definition: TGX11.cxx:120
virtual Int_t GetSize() const
Returns size of this element in bytes.
static const Int_t kRegrouped
virtual Bool_t HasCounter() const
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
double func(double *x, double *p)
Definition: stressTF1.cxx:213
void PrintDebug(TBuffer &buffer, void *object) const
#define R__LOCKGUARD(mutex)
static TConfiguredAction GetConvertCollectionReadAction(Int_t oldtype, Int_t newtype, TConfiguration *conf)
void Compile()
loop on the TStreamerElement list regroup members with same type Store predigested information into l...
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)=0
TClassRef fClass
Definition: TVirtualArray.h:28
Mother of all ROOT objects.
Definition: TObject.h:37
Int_t GetNewType() const
virtual UInt_t Size() const =0
typedef void((*Func_t)())
const int increment
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseFastArrayV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
const char * GetTypeName() const
INLINE_TEMPLATE_ARGS Int_t ReadTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
TClass * GetNewClass() const
INLINE_TEMPLATE_ARGS void ReadArraySTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
static const char * R__GetSymbolName(voidfunc func)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
R__EXTERN Int_t gDebug
Definition: Rtypes.h:83
INLINE_TEMPLATE_ARGS Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
void *(* Next_t)(void *iter, const void *end)
virtual ULong_t GetMethod() const
Int_t GenericReadAction(TBuffer &buf, void *addr, const TConfiguration *config)
const char * GetErrorMessage() const
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
virtual Int_t GetSize() const
Definition: TCollection.h:89
Abstract Interface class describing Streamer information for one class.
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.
Int_t GetOffset() const
void(* DeleteTwoIterators_t)(void *begin, void *end)
Base class of the Configurations.
const Bool_t kTRUE
Definition: RtypesCore.h:91
UInt_t fLength
Number of element in a fixed length array.
Int_t GetType() const
const Int_t n
Definition: legend1.C:16
INLINE_TEMPLATE_ARGS void ReadSTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
TStreamerInfoActions::TActionSequence * GetWriteMemberWiseActions(Bool_t forCollection)
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
TCompInfo_t * fCompInfo
Access to compiled information (for legacy code)