ROOT  6.07/01
Reference Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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
74  }
75 
76  void TConfiguration::Print() const
77  {
78  // Inform the user what we are about to stream.
79 
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.
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 
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  {
960  return kVectorLooper;
961  } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
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>
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 /* kBOOL_t = */ 21:
1961  case TStreamerInfo::kBool: return TConfiguredAction( Looper::ReadCollectionBool, conf ); break;
1962  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<Char_t>, conf ); break;
1963  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<Short_t>,conf ); break;
1964  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<Int_t>, conf ); break;
1965  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long_t>, conf ); break;
1966  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<Long64_t>, conf ); break;
1967  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadCollectionBasicType<Float_t>, conf ); break;
1968  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadCollectionBasicType<Double_t>, conf ); break;
1969  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadCollectionBasicType<UChar_t>, conf ); break;
1970  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadCollectionBasicType<UShort_t>, conf ); break;
1971  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadCollectionBasicType<UInt_t>, conf ); break;
1972  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong_t>, conf ); break;
1973  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadCollectionBasicType<ULong64_t>, conf ); break;
1974  case TStreamerInfo::kBits: Error("GetNumericCollectionReadAction","There is no support for kBits outside of a TObject."); break;
1975  case TStreamerInfo::kFloat16: {
1976  TConfigSTL *alternate = new TConfSTLNoFactor(conf,12);
1977  delete conf;
1978  return TConfiguredAction( Looper::ReadCollectionFloat16, alternate );
1979  // if (element->GetFactor() != 0) {
1980  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
1981  // } else {
1982  // Int_t nbits = (Int_t)element->GetXmin();
1983  // if (!nbits) nbits = 12;
1984  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
1985  // }
1986  break;
1987  }
1988  case TStreamerInfo::kDouble32: {
1989  TConfigSTL *alternate = new TConfSTLNoFactor(conf,0);
1990  delete conf;
1991  return TConfiguredAction( Looper::ReadCollectionDouble32, alternate );
1992  // if (element->GetFactor() != 0) {
1993  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
1994  // } else {
1995  // Int_t nbits = (Int_t)element->GetXmin();
1996  // if (!nbits) {
1997  // return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
1998  // } else {
1999  // return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2000  // }
2001  // }
2002  break;
2003  }
2004  }
2005  Fatal("GetNumericCollectionReadAction","Is confused about %d",type);
2006  R__ASSERT(0); // We should never be here
2007  return TConfiguredAction();
2008 }
2009 
2010 template <typename Looper, typename From>
2012 {
2013  switch (newtype) {
2014  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,bool>::Action, conf ); break;
2015  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,char>::Action, conf ); break;
2016  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,short>::Action, conf ); break;
2017  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Int_t>::Action, conf ); break;
2018  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long_t>::Action, conf ); break;
2019  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,Long64_t>::Action, conf ); break;
2020  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2021  case TStreamerInfo::kFloat16: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,float>::Action, conf ); break;
2022  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2023  case TStreamerInfo::kDouble32:return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,double>::Action, conf ); break;
2024  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UChar_t>::Action, conf ); break;
2025  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UShort_t>::Action, conf ); break;
2026  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2027  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong_t>::Action, conf ); break;
2028  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,ULong64_t>::Action, conf ); break;
2029  case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ConvertCollectionBasicType<From,UInt_t>::Action, conf ); break;
2030  default:
2031  break;
2032  }
2033  R__ASSERT(0); // We should never be here
2034  return TConfiguredAction();
2035 }
2036 
2037 template <typename Looper>
2039 {
2040  switch (oldtype) {
2041  case TStreamerInfo::kBool:
2042  return GetConvertCollectionReadActionFrom<Looper,Bool_t>(newtype, conf );
2043  break;
2044  case TStreamerInfo::kChar:
2045  return GetConvertCollectionReadActionFrom<Looper,Char_t>(newtype, conf );
2046  break;
2047  case TStreamerInfo::kShort:
2048  return GetConvertCollectionReadActionFrom<Looper,Short_t>(newtype, conf );
2049  break;
2050  case TStreamerInfo::kInt:
2051  return GetConvertCollectionReadActionFrom<Looper,Int_t>(newtype, conf );
2052  break;
2053  case TStreamerInfo::kLong:
2054  return GetConvertCollectionReadActionFrom<Looper,Long_t>(newtype, conf );
2055  break;
2057  return GetConvertCollectionReadActionFrom<Looper,Long64_t>(newtype, conf );
2058  break;
2059  case TStreamerInfo::kFloat:
2060  return GetConvertCollectionReadActionFrom<Looper,Float_t>( newtype, conf );
2061  break;
2063  return GetConvertCollectionReadActionFrom<Looper,Double_t>(newtype, conf );
2064  break;
2065  case TStreamerInfo::kUChar:
2066  return GetConvertCollectionReadActionFrom<Looper,UChar_t>(newtype, conf );
2067  break;
2069  return GetConvertCollectionReadActionFrom<Looper,UShort_t>(newtype, conf );
2070  break;
2071  case TStreamerInfo::kUInt:
2072  return GetConvertCollectionReadActionFrom<Looper,UInt_t>(newtype, conf );
2073  break;
2074  case TStreamerInfo::kULong:
2075  return GetConvertCollectionReadActionFrom<Looper,ULong_t>(newtype, conf );
2076  break;
2078  return GetConvertCollectionReadActionFrom<Looper,ULong64_t>(newtype, conf );
2079  break;
2081  return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Float16_t> >( newtype, conf );
2082  break;
2084  return GetConvertCollectionReadActionFrom<Looper,NoFactorMarker<Double32_t> >( newtype, conf );
2085  break;
2086  case TStreamerInfo::kBits:
2087  Error("GetConvertCollectionReadAction","There is no support for kBits outside of a TObject.");
2088  break;
2089  default:
2090  break;
2091  }
2092  R__ASSERT(0); // We should never be here
2093  return TConfiguredAction();
2094 }
2095 
2096 template <class Looper>
2098 {
2099  switch (type) {
2100  // Read basic types.
2101  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template ReadBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2102  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template ReadBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2103  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template ReadBasicType<Short_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2104  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template ReadBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2105  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template ReadBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2106  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template ReadBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2107  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template ReadBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2108  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template ReadBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2109  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template ReadBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2110  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template ReadBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2111  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template ReadBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2112  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template ReadBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2113  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template ReadBasicType<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2114  case TStreamerInfo::kBits: return TConfiguredAction( Looper::template ReadAction<TStreamerInfoActions::ReadBasicType<BitsMarker> > , new TBitsConfiguration(info,i,compinfo,offset) ); break;
2115  case TStreamerInfo::kFloat16: {
2116  if (element->GetFactor() != 0) {
2117  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2118  } else {
2119  Int_t nbits = (Int_t)element->GetXmin();
2120  if (!nbits) nbits = 12;
2121  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2122  }
2123  break;
2124  }
2125  case TStreamerInfo::kDouble32: {
2126  if (element->GetFactor() != 0) {
2127  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2128  } else {
2129  Int_t nbits = (Int_t)element->GetXmin();
2130  if (!nbits) {
2131  return TConfiguredAction( Looper::template ReadAction<ConvertBasicType<float,double>::Action >, new TConfiguration(info,i,compinfo,offset) );
2132  } else {
2133  return TConfiguredAction( Looper::template ReadAction<ReadBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
2134  }
2135  }
2136  break;
2137  }
2138  case TStreamerInfo::kTNamed: return TConfiguredAction( Looper::template ReadAction<ReadTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
2139  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2140  // Streamer alltogether.
2141  case TStreamerInfo::kTObject: return TConfiguredAction( Looper::template ReadAction<ReadTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
2142  case TStreamerInfo::kTString: return TConfiguredAction( Looper::template ReadAction<ReadTString >, new TConfiguration(info,i,compinfo,offset) ); break;
2146  case TStreamerInfo::kSTL: return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) ); break;
2147  case TStreamerInfo::kBase: return TConfiguredAction( Looper::ReadBase, new TGenericConfiguration(info,i,compinfo) ); break;
2148 
2149  // Conversions.
2151  return GetCollectionReadConvertAction<Looper,Bool_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2152  break;
2154  return GetCollectionReadConvertAction<Looper,Char_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2155  break;
2157  return GetCollectionReadConvertAction<Looper,Short_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2158  break;
2160  return GetCollectionReadConvertAction<Looper,Int_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2161  break;
2163  return GetCollectionReadConvertAction<Looper,Long_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2164  break;
2166  return GetCollectionReadConvertAction<Looper,Long64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2167  break;
2169  return GetCollectionReadConvertAction<Looper,Float_t>( element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2170  break;
2172  return GetCollectionReadConvertAction<Looper,Double_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2173  break;
2175  return GetCollectionReadConvertAction<Looper,UChar_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2176  break;
2178  return GetCollectionReadConvertAction<Looper,UShort_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2179  break;
2181  return GetCollectionReadConvertAction<Looper,UInt_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2182  break;
2184  return GetCollectionReadConvertAction<Looper,ULong_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2185  break;
2187  return GetCollectionReadConvertAction<Looper,ULong64_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2188  break;
2190  return GetCollectionReadConvertAction<Looper,BitsMarker>(element->GetNewType(), new TBitsConfiguration(info,i,compinfo,offset) );
2191  break;
2193  if (element->GetFactor() != 0) {
2194  return GetCollectionReadConvertAction<Looper,WithFactorMarker<float> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2195  } else {
2196  Int_t nbits = (Int_t)element->GetXmin();
2197  if (!nbits) nbits = 12;
2198  return GetCollectionReadConvertAction<Looper,NoFactorMarker<float> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2199  }
2200  break;
2201  }
2203  if (element->GetFactor() != 0) {
2204  return GetCollectionReadConvertAction<Looper,WithFactorMarker<double> >(element->GetNewType(), new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
2205  } else {
2206  Int_t nbits = (Int_t)element->GetXmin();
2207  if (!nbits) {
2208  return GetCollectionReadConvertAction<Looper,Float_t>(element->GetNewType(), new TConfiguration(info,i,compinfo,offset) );
2209  } else {
2210  return GetCollectionReadConvertAction<Looper,NoFactorMarker<double> >(element->GetNewType(), new TConfNoFactor(info,i,compinfo,offset,nbits) );
2211  }
2212  }
2213  break;
2214  }
2215  default:
2216  return TConfiguredAction( Looper::GenericRead, new TGenericConfiguration(info,i,compinfo) );
2217  break;
2218  }
2219  R__ASSERT(0); // We should never be here
2220  return TConfiguredAction();
2221 }
2222 
2223 template <class Looper>
2225  switch (type) {
2226  // read basic types
2227  case TStreamerInfo::kBool: return TConfiguredAction( Looper::template WriteBasicType<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2228  case TStreamerInfo::kChar: return TConfiguredAction( Looper::template WriteBasicType<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2229  case TStreamerInfo::kShort: return TConfiguredAction( Looper::template WriteBasicType<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2230  case TStreamerInfo::kInt: return TConfiguredAction( Looper::template WriteBasicType<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2231  case TStreamerInfo::kLong: return TConfiguredAction( Looper::template WriteBasicType<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2232  case TStreamerInfo::kLong64: return TConfiguredAction( Looper::template WriteBasicType<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2233  case TStreamerInfo::kFloat: return TConfiguredAction( Looper::template WriteBasicType<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2234  case TStreamerInfo::kDouble: return TConfiguredAction( Looper::template WriteBasicType<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2235  case TStreamerInfo::kUChar: return TConfiguredAction( Looper::template WriteBasicType<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2236  case TStreamerInfo::kUShort: return TConfiguredAction( Looper::template WriteBasicType<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2237  case TStreamerInfo::kUInt: return TConfiguredAction( Looper::template WriteBasicType<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2238  case TStreamerInfo::kULong: return TConfiguredAction( Looper::template WriteBasicType<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
2239  case TStreamerInfo::kULong64: return TConfiguredAction( Looper::template WriteBasicType<ULong64_t>,new TConfiguration(info,i,compinfo,offset) ); break;
2240  // the simple type missing are kBits and kCounter.
2241  default:
2242  return TConfiguredAction( Looper::GenericWrite, new TConfiguration(info,i,compinfo,0 /* 0 because we call the legacy code */) );
2243  }
2244  R__ASSERT(0); // We should never be here
2245  return TConfiguredAction();
2246 }
2247 
2248 
2249 ////////////////////////////////////////////////////////////////////////////////
2250 /// loop on the TStreamerElement list
2251 /// regroup members with same type
2252 /// Store predigested information into local arrays. This saves a huge amount
2253 /// of time compared to an explicit iteration on all elements.
2254 
2256 {
2257  if (IsCompiled()) {
2258  //Error("Compile","can only be called once; this first call generates both the optimized and memberwise actions.");
2259  return;
2260  }
2262 
2263  // fprintf(stderr,"Running Compile for %s %d %d req=%d,%d\n",GetName(),fClassVersion,fOptimized,CanOptimize(),TestBit(kCannotOptimize));
2264 
2265  // if (IsCompiled() && (!fOptimized || (CanOptimize() && !TestBit(kCannotOptimize)))) return;
2266  fOptimized = kFALSE;
2267  fNdata = 0;
2268  fNfulldata = 0;
2269 
2270  TObjArray* infos = (TObjArray*) gROOT->GetListOfStreamerInfo();
2271  if (fNumber >= infos->GetSize()) {
2272  infos->AddAtAndExpand(this, fNumber);
2273  } else {
2274  if (!infos->At(fNumber)) {
2275  infos->AddAt(this, fNumber);
2276  }
2277  }
2278 
2279  assert(fComp == 0 && fCompFull == 0 && fCompOpt == 0);
2280 
2281 
2283 
2284 
2287 
2290 
2293 
2296 
2299 
2302 
2303  if (!ndata) {
2304  // This may be the case for empty classes (e.g., TAtt3D).
2305  // We still need to properly set the size of emulated classes (i.e. add the virtual table)
2307  fSize = sizeof(TStreamerInfo*);
2308  }
2309  fComp = new TCompInfo[1];
2310  fCompFull = new TCompInfo*[1];
2311  fCompOpt = new TCompInfo*[1];
2312  fCompOpt[0] = fCompFull[0] = &(fComp[0]);
2313  SetIsCompiled();
2314  return;
2315  }
2316 
2317  // At most half of the elements can be used to hold optimized versions.
2318  // We use the bottom to hold the optimized-into elements and the non-optimized elements
2319  // and the top to hold the original copy of the optimized out elements.
2320  fNslots = ndata + ndata/2 + 1;
2321  Int_t optiOut = 0;
2322 
2323  fComp = new TCompInfo[fNslots];
2324  fCompFull = new TCompInfo*[ndata];
2325  fCompOpt = new TCompInfo*[ndata];
2326 
2327  TStreamerElement* element;
2328  TStreamerElement* previous = 0;
2329  Int_t keep = -1;
2330  Int_t i;
2331 
2332  if (!CanOptimize()) {
2334  }
2335 
2336  Bool_t isOptimized = kFALSE;
2337  Bool_t previousOptimized = kFALSE;
2338 
2339  for (i = 0; i < ndata; ++i) {
2340  element = (TStreamerElement*) fElements->At(i);
2341  if (!element) {
2342  break;
2343  }
2344 
2345  Int_t asize = element->GetSize();
2346  if (element->GetArrayLength()) {
2347  asize /= element->GetArrayLength();
2348  }
2349  fComp[fNdata].fType = element->GetType();
2350  fComp[fNdata].fNewType = element->GetNewType();
2351  fComp[fNdata].fOffset = element->GetOffset();
2352  fComp[fNdata].fLength = element->GetArrayLength();
2353  fComp[fNdata].fElem = element;
2354  fComp[fNdata].fMethod = element->GetMethod();
2355  fComp[fNdata].fClass = element->GetClassPointer();
2356  fComp[fNdata].fNewClass = element->GetNewClass();
2358  fComp[fNdata].fStreamer = element->GetStreamer();
2359 
2360  // try to group consecutive members of the same type
2361  if (!TestBit(kCannotOptimize)
2362  && (keep >= 0)
2363  && (element->GetType() >=0)
2364  && (element->GetType() < 10)
2365  && (fComp[fNdata].fType == fComp[fNdata].fNewType)
2366  && (fComp[keep].fMethod == 0)
2367  && (element->GetType() > 0)
2368  && (element->GetArrayDim() == 0)
2369  && (fComp[keep].fType < kObject)
2370  && (fComp[keep].fType != kCharStar) /* do not optimize char* */
2371  && (element->GetType() == (fComp[keep].fType%kRegrouped))
2372  && ((element->GetOffset()-fComp[keep].fOffset) == (fComp[keep].fLength)*asize)
2373  && ((fOldVersion<6) || !previous || /* In version of TStreamerInfo less than 6, the Double32_t were merged even if their annotation (aka factor) were different */
2374  ((element->GetFactor() == previous->GetFactor())
2375  && (element->GetXmin() == previous->GetXmin())
2376  && (element->GetXmax() == previous->GetXmax())
2377  )
2378  )
2381  // kWholeObject and kDoNotDelete do not apply to numerical elements.
2382  )
2383  {
2384  if (!previousOptimized) {
2385  // The element was not yet optimized we first need to copy it into
2386  // the set of original copies.
2387  fComp[fNslots - (++optiOut) ] = fComp[keep]; // Copy the optimized out elements.
2388  fCompFull[fNfulldata-1] = &(fComp[fNslots - optiOut]); // Reset the pointer in the full list.
2389  }
2390  fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the optimized out elements.
2391  fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
2392 
2393  R__ASSERT( keep < (fNslots - optiOut) );
2394 
2395  if (fComp[keep].fLength == 0) {
2396  fComp[keep].fLength++;
2397  }
2398  fComp[keep].fLength++;
2399  fComp[keep].fType = element->GetType() + kRegrouped;
2400  isOptimized = kTRUE;
2401  previousOptimized = kTRUE;
2402  } else if (element->GetType() < 0) {
2403 
2404  // -- Deal with an ignored TObject base class.
2405  // Note: The only allowed negative value here is -1,
2406  // and signifies that Build() has found a TObject
2407  // base class and TClass::IgnoreTObjectStreamer() was
2408  // called. In this case the compiled version of the
2409  // elements omits the TObject base class element,
2410  // which has to be compensated for by TTree::Bronch()
2411  // when it is making branches for a split object.
2412  fComp[fNslots - (++optiOut) ] = fComp[fNdata]; // Copy the 'ignored' element.
2413  fCompFull[fNfulldata] = &(fComp[fNslots - optiOut]);
2414  keep = -1;
2415  previousOptimized = kFALSE;
2416 
2417  } else {
2418  if (fComp[fNdata].fNewType != fComp[fNdata].fType) {
2419  if (fComp[fNdata].fNewType > 0) {
2420  if ( (fComp[fNdata].fNewType == kObjectp || fComp[fNdata].fNewType == kAnyp
2421  || fComp[fNdata].fNewType == kObject || fComp[fNdata].fNewType == kAny
2422  || fComp[fNdata].fNewType == kTObject || fComp[fNdata].fNewType == kTNamed || fComp[fNdata].fNewType == kTString)
2423  && (fComp[fNdata].fType == kObjectp || fComp[fNdata].fType == kAnyp
2424  || fComp[fNdata].fType == kObject || fComp[fNdata].fType == kAny
2426  ) {
2428  } else if (fComp[fNdata].fType != kCounter) {
2429  fComp[fNdata].fType += kConv;
2430  }
2431  } else {
2432  if (fComp[fNdata].fType == kCounter) {
2433  Warning("Compile", "Counter %s should not be skipped from class %s", element->GetName(), GetName());
2434  }
2435  fComp[fNdata].fType += kSkip;
2436  }
2437  }
2438  fCompOpt[fNdata] = &(fComp[fNdata]);
2440 
2441  R__ASSERT( fNdata < (fNslots - optiOut) );
2442 
2443  keep = fNdata;
2444  if (fComp[keep].fLength == 0) {
2445  fComp[keep].fLength = 1;
2446  }
2447  fNdata++;
2448  previousOptimized = kFALSE;
2449  }
2450  // The test 'fMethod[keep] == 0' fails to detect a variable size array
2451  // if the counter happens to have an offset of zero, so let's explicitly
2452  // prevent for here.
2453  if (element->HasCounter()) keep = -1;
2454  ++fNfulldata;
2455  previous = element;
2456  }
2457 
2458  for (i = 0; i < fNdata; ++i) {
2459  if (!fCompOpt[i]->fElem || fCompOpt[i]->fElem->GetType()< 0) {
2460  continue;
2461  }
2464  }
2465  for (i = 0; i < fNfulldata; ++i) {
2466  if (!fCompFull[i]->fElem || fCompFull[i]->fElem->GetType()< 0) {
2467  continue;
2468  }
2473  }
2474  ComputeSize();
2475 
2476  fOptimized = isOptimized;
2477  SetIsCompiled();
2478 
2479  if (gDebug > 0) {
2480  ls();
2481  }
2482 }
2483 
2484 template <typename From>
2486 {
2487  switch (newtype) {
2488  case TStreamerInfo::kBool: sequence->AddAction( ConvertBasicType<From,bool>::Action, conf ); break;
2489  case TStreamerInfo::kChar: sequence->AddAction( ConvertBasicType<From,char>::Action, conf ); break;
2490  case TStreamerInfo::kShort: sequence->AddAction( ConvertBasicType<From,short>::Action, conf ); break;
2491  case TStreamerInfo::kInt: sequence->AddAction( ConvertBasicType<From,Int_t>::Action, conf ); break;
2492  case TStreamerInfo::kLong: sequence->AddAction( ConvertBasicType<From,Long_t>::Action,conf ); break;
2493  case TStreamerInfo::kLong64: sequence->AddAction( ConvertBasicType<From,Long64_t>::Action, conf ); break;
2494  case TStreamerInfo::kFloat: sequence->AddAction( ConvertBasicType<From,float>::Action, conf ); break;
2495  case TStreamerInfo::kFloat16: sequence->AddAction( ConvertBasicType<From,float>::Action, conf ); break;
2496  case TStreamerInfo::kDouble: sequence->AddAction( ConvertBasicType<From,double>::Action, conf ); break;
2497  case TStreamerInfo::kDouble32:sequence->AddAction( ConvertBasicType<From,double>::Action, conf ); break;
2498  case TStreamerInfo::kUChar: sequence->AddAction( ConvertBasicType<From,UChar_t>::Action, conf ); break;
2499  case TStreamerInfo::kUShort: sequence->AddAction( ConvertBasicType<From,UShort_t>::Action, conf ); break;
2500  case TStreamerInfo::kUInt: sequence->AddAction( ConvertBasicType<From,UInt_t>::Action, conf ); break;
2501  case TStreamerInfo::kULong: sequence->AddAction( ConvertBasicType<From,ULong_t>::Action, conf ); break;
2502  case TStreamerInfo::kULong64: sequence->AddAction( ConvertBasicType<From,ULong64_t>::Action,conf ); break;
2503  case TStreamerInfo::kBits: sequence->AddAction( ConvertBasicType<From,UInt_t>::Action, conf ); break;
2504  }
2505 }
2506 
2507 ////////////////////////////////////////////////////////////////////////////////
2508 /// Add a read action for the given element.
2509 
2511 {
2512  TStreamerElement *element = compinfo->fElem;
2513 
2514  if (element->TestBit(TStreamerElement::kWrite)) return;
2515 
2516  switch (compinfo->fType) {
2517  // read basic types
2518  case TStreamerInfo::kBool: readSequence->AddAction( ReadBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2519  case TStreamerInfo::kChar: readSequence->AddAction( ReadBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2520  case TStreamerInfo::kShort: readSequence->AddAction( ReadBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2521  case TStreamerInfo::kInt: readSequence->AddAction( ReadBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2522  case TStreamerInfo::kLong: readSequence->AddAction( ReadBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2523  case TStreamerInfo::kLong64: readSequence->AddAction( ReadBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2524  case TStreamerInfo::kFloat: readSequence->AddAction( ReadBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2525  case TStreamerInfo::kDouble: readSequence->AddAction( ReadBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2526  case TStreamerInfo::kUChar: readSequence->AddAction( ReadBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2527  case TStreamerInfo::kUShort: readSequence->AddAction( ReadBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2528  case TStreamerInfo::kUInt: readSequence->AddAction( ReadBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2529  case TStreamerInfo::kULong: readSequence->AddAction( ReadBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2530  case TStreamerInfo::kULong64: readSequence->AddAction( ReadBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2531  case TStreamerInfo::kBits: readSequence->AddAction( ReadBasicType<BitsMarker>, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2532  case TStreamerInfo::kFloat16: {
2533  if (element->GetFactor() != 0) {
2534  readSequence->AddAction( ReadBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2535  } else {
2536  Int_t nbits = (Int_t)element->GetXmin();
2537  if (!nbits) nbits = 12;
2538  readSequence->AddAction( ReadBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2539  }
2540  break;
2541  }
2542  case TStreamerInfo::kDouble32: {
2543  if (element->GetFactor() != 0) {
2544  readSequence->AddAction( ReadBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2545  } else {
2546  Int_t nbits = (Int_t)element->GetXmin();
2547  if (!nbits) {
2548  readSequence->AddAction( ConvertBasicType<float,double>::Action, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2549  } else {
2550  readSequence->AddAction( ReadBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2551  }
2552  }
2553  break;
2554  }
2555  case TStreamerInfo::kTNamed: readSequence->AddAction( ReadTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2556  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2557  // Streamer alltogether.
2558  case TStreamerInfo::kTObject: readSequence->AddAction( ReadTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2559  case TStreamerInfo::kTString: readSequence->AddAction( ReadTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2560  case TStreamerInfo::kSTL: {
2561  TClass *newClass = element->GetNewClass();
2562  TClass *oldClass = element->GetClassPointer();
2563  Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
2564 
2565  if (element->GetArrayLength() <= 1) {
2566  if (fOldVersion<3){ // case of old TStreamerInfo
2567  if (newClass && newClass != oldClass) {
2568  if (element->GetStreamer()) {
2569  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2570  } else {
2571  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2572  }
2573  } else {
2574  if (element->GetStreamer()) {
2575  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2576  } else {
2577  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2578  }
2579  }
2580  } else {
2581  if (newClass && newClass != oldClass) {
2582  if (element->GetStreamer()) {
2583  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2584  } else {
2585  if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
2586  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2587  } else {
2588  switch (SelectLooper(*newClass->GetCollectionProxy())) {
2589  case kVectorLooper:
2590  readSequence->AddAction(GetConvertCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2591  break;
2592  case kAssociativeLooper:
2593  readSequence->AddAction(GetConvertCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2594  break;
2595  case kVectorPtrLooper:
2596  case kGenericLooper:
2597  default:
2598  // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
2599  readSequence->AddAction(GetConvertCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), newClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase)));
2600  break;
2601  }
2602  }
2603  }
2604  } else {
2605  if (element->GetStreamer()) {
2606  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2607  } else {
2608  if (oldClass->GetCollectionProxy() == 0 || oldClass->GetCollectionProxy()->GetValueClass() || oldClass->GetCollectionProxy()->HasPointers() ) {
2609  readSequence->AddAction(ReadSTL<ReadSTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2610  } else {
2611  switch (SelectLooper(*oldClass->GetCollectionProxy())) {
2612  case kVectorLooper:
2613  readSequence->AddAction(GetNumericCollectionReadAction<VectorLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2614  break;
2615  case kAssociativeLooper:
2616  readSequence->AddAction(GetNumericCollectionReadAction<AssociativeLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2617  break;
2618  case kVectorPtrLooper:
2619  case kGenericLooper:
2620  default:
2621  // For now TBufferXML would force use to allocate the data buffer each time and copy into the real thing.
2622  readSequence->AddAction(GetNumericCollectionReadAction<GenericLooper>(oldClass->GetCollectionProxy()->GetType(), new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase)));
2623  break;
2624  }
2625  }
2626  }
2627  }
2628  }
2629  } else {
2630  if (fOldVersion<3){ // case of old TStreamerInfo
2631  if (newClass && newClass != oldClass) {
2632  if (element->GetStreamer()) {
2633  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2634  } else {
2635  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2636  }
2637  } else {
2638  if (element->GetStreamer()) {
2639  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamerV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2640  } else {
2641  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArrayV2>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2642  }
2643  }
2644  } else {
2645  if (newClass && newClass != oldClass) {
2646  if (element->GetStreamer()) {
2647  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2648  } else {
2649  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseChangedClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2650  }
2651  } else {
2652  if (element->GetStreamer()) {
2653  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2654  } else {
2655  readSequence->AddAction(ReadSTL<ReadArraySTLMemberWiseSameClass,ReadSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2656  }
2657  }
2658  }
2659  }
2660  break;
2661  }
2662 
2664  AddReadConvertAction<Bool_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2665  break;
2667  AddReadConvertAction<Char_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2668  break;
2670  AddReadConvertAction<Short_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2671  break;
2673  AddReadConvertAction<Int_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2674  break;
2676  AddReadConvertAction<Long_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2677  break;
2679  AddReadConvertAction<Long64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2680  break;
2682  AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2683  break;
2685  AddReadConvertAction<Double_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2686  break;
2688  AddReadConvertAction<UChar_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2689  break;
2691  AddReadConvertAction<UShort_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2692  break;
2694  AddReadConvertAction<UInt_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2695  break;
2697  AddReadConvertAction<ULong_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2698  break;
2700  AddReadConvertAction<ULong64_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2701  break;
2703  AddReadConvertAction<BitsMarker>(readSequence, compinfo->fNewType, new TBitsConfiguration(this,i,compinfo,compinfo->fOffset) );
2704  break;
2706  if (element->GetFactor() != 0) {
2707  AddReadConvertAction<WithFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2708  } else {
2709  Int_t nbits = (Int_t)element->GetXmin();
2710  if (!nbits) nbits = 12;
2711  AddReadConvertAction<NoFactorMarker<float> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2712  }
2713  break;
2714  }
2716  if (element->GetFactor() != 0) {
2717  AddReadConvertAction<WithFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2718  } else {
2719  Int_t nbits = (Int_t)element->GetXmin();
2720  if (!nbits) {
2721  AddReadConvertAction<Float_t>(readSequence, compinfo->fNewType, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2722  } else {
2723  AddReadConvertAction<NoFactorMarker<double> >(readSequence, compinfo->fNewType, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2724  }
2725  }
2726  break;
2727  }
2728  default:
2729  readSequence->AddAction( GenericReadAction, new TGenericConfiguration(this,i,compinfo) );
2730  break;
2731  }
2732  if (element->TestBit(TStreamerElement::kCache)) {
2733  TConfiguredAction action( readSequence->fActions.back() ); // Action is moved, we must pop it next.
2734  readSequence->fActions.pop_back();
2735  readSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2736  }
2737 }
2738 
2739 ////////////////////////////////////////////////////////////////////////////////
2740 /// Add a read action for the given element.
2741 /// This is for streaming via a TClonesArray (or a vector of pointers of this type).
2742 
2744 {
2745  TStreamerElement *element = compinfo->fElem;
2746 
2747  if (element->TestBit(TStreamerElement::kWrite)) return;
2748 
2749  if (element->TestBit(TStreamerElement::kCache)) {
2750  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2751  readSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2752  } else {
2753  readSequence->AddAction( GetCollectionReadAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2754  }
2755 }
2756 
2757 ////////////////////////////////////////////////////////////////////////////////
2758 
2760 {
2761  TStreamerElement *element = compinfo->fElem;
2762  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
2763  // Skip element cached for reading purposes.
2764  return;
2765  }
2766  if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
2767  // Skip artificial element used for reading purposes.
2768  return;
2769  }
2770  switch (compinfo->fType) {
2771  // write basic types
2772  case TStreamerInfo::kBool: writeSequence->AddAction( WriteBasicType<Bool_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2773  case TStreamerInfo::kChar: writeSequence->AddAction( WriteBasicType<Char_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2774  case TStreamerInfo::kShort: writeSequence->AddAction( WriteBasicType<Short_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2775  case TStreamerInfo::kInt: writeSequence->AddAction( WriteBasicType<Int_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2776  case TStreamerInfo::kLong: writeSequence->AddAction( WriteBasicType<Long_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2777  case TStreamerInfo::kLong64: writeSequence->AddAction( WriteBasicType<Long64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2778  case TStreamerInfo::kFloat: writeSequence->AddAction( WriteBasicType<Float_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2779  case TStreamerInfo::kDouble: writeSequence->AddAction( WriteBasicType<Double_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2780  case TStreamerInfo::kUChar: writeSequence->AddAction( WriteBasicType<UChar_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2781  case TStreamerInfo::kUShort: writeSequence->AddAction( WriteBasicType<UShort_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2782  case TStreamerInfo::kUInt: writeSequence->AddAction( WriteBasicType<UInt_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2783  case TStreamerInfo::kULong: writeSequence->AddAction( WriteBasicType<ULong_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2784  case TStreamerInfo::kULong64: writeSequence->AddAction( WriteBasicType<ULong64_t>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2785  // case TStreamerInfo::kBits: writeSequence->AddAction( WriteBasicType<BitsMarker>, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2786  /*case TStreamerInfo::kFloat16: {
2787  if (element->GetFactor() != 0) {
2788  writeSequence->AddAction( WriteBasicType_WithFactor<float>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2789  } else {
2790  Int_t nbits = (Int_t)element->GetXmin();
2791  if (!nbits) nbits = 12;
2792  writeSequence->AddAction( WriteBasicType_NoFactor<float>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2793  }
2794  break;
2795  } */
2796  /*case TStreamerInfo::kDouble32: {
2797  if (element->GetFactor() != 0) {
2798  writeSequence->AddAction( WriteBasicType_WithFactor<double>, new TConfWithFactor(this,i,compinfo,compinfo->fOffset,element->GetFactor(),element->GetXmin()) );
2799  } else {
2800  Int_t nbits = (Int_t)element->GetXmin();
2801  if (!nbits) {
2802  writeSequence->AddAction( ConvertBasicType<float,double>, new TConfiguration(this,i,compinfo,compinfo->fOffset) );
2803  } else {
2804  writeSequence->AddAction( WriteBasicType_NoFactor<double>, new TConfNoFactor(this,i,compinfo,compinfo->fOffset,nbits) );
2805  }
2806  }
2807  break;
2808  } */
2809  //case TStreamerInfo::kTNamed: writeSequence->AddAction( WriteTNamed, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2810  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
2811  // Streamer alltogether.
2812  //case TStreamerInfo::kTObject: writeSequence->AddAction( WriteTObject, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2813  //case TStreamerInfo::kTString: writeSequence->AddAction( WriteTString, new TConfiguration(this,i,compinfo,compinfo->fOffset) ); break;
2814  /*case TStreamerInfo::kSTL: {
2815  TClass *newClass = element->GetNewClass();
2816  TClass *oldClass = element->GetClassPointer();
2817  Bool_t isSTLbase = element->IsBase() && element->IsA()!=TStreamerBase::Class();
2818 
2819  if (element->GetArrayLength() <= 1) {
2820  if (newClass && newClass != oldClass) {
2821  if (element->GetStreamer()) {
2822  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2823  } else {
2824  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,newClass,element->GetTypeName(),isSTLbase));
2825  }
2826  } else {
2827  if (element->GetStreamer()) {
2828  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2829  } else {
2830  writeSequence->AddAction(WriteSTL<WriteSTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,1,oldClass,element->GetTypeName(),isSTLbase));
2831  }
2832  }
2833  } else {
2834  if (newClass && newClass != oldClass) {
2835  if (element->GetStreamer()) {
2836  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2837  } else {
2838  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseChangedClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,newClass,element->GetTypeName(),isSTLbase));
2839  }
2840  } else {
2841  if (element->GetStreamer()) {
2842  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseStreamer>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetStreamer(),element->GetTypeName(),isSTLbase));
2843  } else {
2844  writeSequence->AddAction(WriteSTL<WriteArraySTLMemberWiseSameClass,WriteSTLObjectWiseFastArray>, new TConfigSTL(this,i,compinfo,compinfo->fOffset,element->GetArrayLength(),oldClass,element->GetTypeName(),isSTLbase));
2845  }
2846  }
2847  }
2848  break;
2849  } */
2850  default:
2851  writeSequence->AddAction( GenericWriteAction, new TGenericConfiguration(this,i,compinfo) );
2852  break;
2853  }
2854 #if defined(CDJ_NO_COMPILE)
2855  if (element->TestBit(TStreamerElement::kCache)) {
2856  TConfiguredAction action( writeSequence->fActions.back() ); // Action is moved, we must pop it next.
2857  writeSequence->fActions.pop_back();
2858  writeSequence->AddAction( UseCache, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2859  }
2860 #endif
2861 }
2862 
2863 ////////////////////////////////////////////////////////////////////////////////
2864 /// This is for streaming via a TClonesArray (or a vector of pointers of this type).
2865 
2867 {
2868  TStreamerElement *element = compinfo->fElem;
2869  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
2870  // Skip element cached for reading purposes.
2871  return;
2872  }
2873  if (element->GetType() >= kArtificial && !element->TestBit(TStreamerElement::kWrite)) {
2874  // Skip artificial element used for reading purposes.
2875  return;
2876  }
2877 
2878 #if defined(CDJ_NO_COMPILE)
2879  if (element->TestBit(TStreamerElement::kCache)) {
2880  TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2881  writeSequence->AddAction( UseCacheVectorPtrLoop, new TConfigurationUseCache(this,action,element->TestBit(TStreamerElement::kRepeat)) );
2882  } else {
2883  writeSequence->Addaction( GetCollectionWriteAction<VectorPtrLooper>(this,element,compinfo->fType,i,compinfo,compinfo->fOffset) );
2884  }
2885 #else
2886  writeSequence->AddAction( VectorPtrLooper::GenericWrite, new TGenericConfiguration(this,i,compinfo) );
2887 #endif
2888 
2889 }
2890 
2891 ////////////////////////////////////////////////////////////////////////////////
2892 /// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
2893 
2895 {
2896  if (info == 0) {
2897  return new TStreamerInfoActions::TActionSequence(0,0);
2898  }
2899 
2900  TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
2901 
2902  UInt_t ndata = info->GetElements()->GetEntries();
2905  {
2906  if (proxy.HasPointers()) {
2907  // Instead of the creating a new one let's copy the one from the StreamerInfo.
2908  delete sequence;
2909 
2910  sequence = sinfo->GetReadMemberWiseActions(kTRUE)->CreateCopy();
2911 
2912  return sequence;
2913  }
2914 
2915  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
2916  Long_t increment = proxy.GetIncrement();
2917  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kTRUE);
2918  } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLunorderedset
2922  {
2923  Long_t increment = proxy.GetIncrement();
2924  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kTRUE);
2925  // sequence->fLoopConfig = new TAssocLoopConfig(proxy);
2926  } else {
2927  sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kTRUE);
2928  }
2929  for (UInt_t i = 0; i < ndata; ++i) {
2930  TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
2931  if (!element) {
2932  break;
2933  }
2934  if (element->GetType() < 0) {
2935  // -- Skip an ignored TObject base class.
2936  // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
2937  // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
2938  // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
2939  // when it is making branches for a split object.
2940  continue;
2941  }
2942  if (element->TestBit(TStreamerElement::kWrite)) {
2943  // Skip element that only for writing.
2944  continue;
2945  }
2946  TStreamerBase *baseEl = dynamic_cast<TStreamerBase*>(element);
2947  if (baseEl) {
2948  if (baseEl->GetErrorMessage()[0]) {
2949  // There was a problem with the checksum, the user likely did not
2950  // increment the version number of the derived class when the
2951  // base class changed. Since we will be member wise streaming
2952  // this class, let's warn the user that something is wrong.
2953  ::Warning("CreateReadMemberWiseActions","%s",
2954  baseEl->GetErrorMessage());
2955  }
2956  }
2957 
2958  TStreamerInfo::TCompInfo_t *compinfo = sinfo->fCompFull[i];
2959 
2960  Int_t asize = element->GetSize();
2961  if (element->GetArrayLength()) {
2962  asize /= element->GetArrayLength();
2963  }
2964  Int_t oldType = element->GetType();
2965  Int_t newType = element->GetNewType();
2966 
2967  Int_t offset = element->GetOffset();
2968  if (newType != oldType) {
2969  if (newType > 0) {
2970  if (oldType != TVirtualStreamerInfo::kCounter) {
2971  oldType += TVirtualStreamerInfo::kConv;
2972  }
2973  } else {
2974  oldType += TVirtualStreamerInfo::kSkip;
2975  }
2976  }
2977  switch (SelectLooper(proxy)) {
2978  case kAssociativeLooper:
2979 // } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
2980 // || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
2981 // sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
2982  case kVectorLooper:
2983  case kVectorPtrLooper:
2984  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
2985  if (element->TestBit(TStreamerElement::kCache)) {
2986  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
2987  sequence->AddAction( UseCacheVectorLoop, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
2988  } else {
2989  sequence->AddAction( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
2990  }
2991  break;
2992  case kGenericLooper:
2993  default:
2994  // The usual collection case.
2995  if (element->TestBit(TStreamerElement::kCache)) {
2996  TConfiguredAction action( GetCollectionReadAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
2997  sequence->AddAction( UseCacheGenericCollection, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
2998  } else {
2999  sequence->AddAction( GetCollectionReadAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
3000  }
3001  break;
3002  }
3003  }
3004  return sequence;
3005 }
3006 
3007 ////////////////////////////////////////////////////////////////////////////////
3008 /// Create the bundle of the actions necessary for the streaming memberwise of the content described by 'info' into the collection described by 'proxy'
3009 
3011 {
3012  if (info == 0) {
3013  return new TStreamerInfoActions::TActionSequence(0,0);
3014  }
3015 
3016  UInt_t ndata = info->GetElements()->GetEntries();
3017  TStreamerInfo *sinfo = static_cast<TStreamerInfo*>(info);
3019 
3021  {
3022  if (proxy.HasPointers()) {
3023  // Instead of the creating a new one let's copy the one from the StreamerInfo.
3024  delete sequence;
3025 
3026  sequence = sinfo->GetWriteMemberWiseActions(kTRUE)->CreateCopy();
3027 
3028  return sequence;
3029  }
3030 
3031  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3032  Long_t increment = proxy.GetIncrement();
3033  sequence->fLoopConfig = new TVectorLoopConfig(increment, /* read */ kFALSE);
3034  /*} else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3035  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)
3036  {
3037  Long_t increment = proxy.GetIncrement();
3038  sequence->fLoopConfig = new TVectorLoopConfig(increment);
3039  // sequence->fLoopConfig = new TAssocLoopConfig(proxy); */
3040  } else {
3041  sequence->fLoopConfig = new TGenericLoopConfig(&proxy, /* read */ kFALSE);
3042  }
3043  for (UInt_t i = 0; i < ndata; ++i) {
3044  TStreamerElement *element = (TStreamerElement*) info->GetElements()->At(i);
3045  if (!element) {
3046  break;
3047  }
3048  if (element->GetType() < 0) {
3049  // -- Skip an ignored TObject base class.
3050  // Note: The only allowed negative value here is -1, and signifies that Build() has found a TObject
3051  // base class and TClass::IgnoreTObjectStreamer() was called. In this case the compiled version of the
3052  // elements omits the TObject base class element, which has to be compensated for by TTree::Bronch()
3053  // when it is making branches for a split object.
3054  continue;
3055  }
3056  if (element->TestBit(TStreamerElement::kCache) && !element->TestBit(TStreamerElement::kWrite)) {
3057  // Skip element cached for reading purposes.
3058  continue;
3059  }
3061  // Skip artificial element used for reading purposes.
3062  continue;
3063  }
3064  TStreamerInfo::TCompInfo *compinfo = sinfo->fCompFull[i];
3065  Int_t asize = element->GetSize();
3066  if (element->GetArrayLength()) {
3067  asize /= element->GetArrayLength();
3068  }
3069  Int_t oldType = element->GetType();
3070  Int_t offset = element->GetOffset();
3071 #if defined(CDJ_NO_COMPILE)
3072  Int_t newType = element->GetNewType();
3073 
3074  if (newType != oldType) {
3075  if (newType > 0) {
3076  if (oldType != TVirtualStreamerInfo::kCounter) {
3077  oldType += TVirtualStreamerInfo::kConv;
3078  }
3079  } else {
3080  oldType += TVirtualStreamerInfo::kSkip;
3081  }
3082  }
3084  /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3085  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) */ )
3086  {
3087 
3088  // We can speed up the iteration in case of vector. We also know that all emulated collection are stored internally as a vector.
3089  if (element->TestBit(TStreamerElement::kCache)) {
3090  TConfiguredAction action( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3091  sequence->AddAction( UseCacheVectorLoop, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
3092  } else {
3093  sequence->AddAction(GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset));
3094  }
3095 
3096  // } else if (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3097  // || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap) {
3098  // sequence->AddAction( GenericAssocCollectionAction, new TConfigSTL(info,i,compinfo,offset,0,proxy.GetCollectionClass(),0,0) );
3099  } else {
3100  // The usual collection case.
3101  if (element->TestBit(TStreamerElement::kCache)) {
3102  TConfiguredAction action( GetWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3103  sequence->AddAction( UseCacheGenericCollection, new TConfigurationUseCache(info,action,element->TestBit(TStreamerElement::kRepeat)) );
3104  } else {
3105  switch (oldType) {
3106  // read basic types
3107  case TVirtualStreamerInfo::kBool: sequence->AddAction( WriteBasicTypeGenericLoop<Bool_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3108  case TVirtualStreamerInfo::kChar: sequence->AddAction( WriteBasicTypeGenericLoop<Char_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3109  case TVirtualStreamerInfo::kShort: sequence->AddAction( WriteBasicTypeGenericLoop<Short_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3110  case TVirtualStreamerInfo::kInt: sequence->AddAction( WriteBasicTypeGenericLoop<Int_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3111  case TVirtualStreamerInfo::kLong: sequence->AddAction( WriteBasicTypeGenericLoop<Long_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3112  case TVirtualStreamerInfo::kLong64: sequence->AddAction( WriteBasicTypeGenericLoop<Long64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3113  case TVirtualStreamerInfo::kFloat: sequence->AddAction( WriteBasicTypeGenericLoop<Float_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3114  case TVirtualStreamerInfo::kDouble: sequence->AddAction( WriteBasicTypeGenericLoop<Double_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3115  case TVirtualStreamerInfo::kUChar: sequence->AddAction( WriteBasicTypeGenericLoop<UChar_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3116  case TVirtualStreamerInfo::kUShort: sequence->AddAction( WriteBasicTypeGenericLoop<UShort_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3117  case TVirtualStreamerInfo::kUInt: sequence->AddAction( WriteBasicTypeGenericLoop<UInt_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3118  case TVirtualStreamerInfo::kULong: sequence->AddAction( WriteBasicTypeGenericLoop<ULong_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3119  case TVirtualStreamerInfo::kULong64: sequence->AddAction( WriteBasicTypeGenericLoop<ULong64_t>, new TConfiguration(info,i,compinfo,offset) ); break;
3120  // case TVirtualStreamerInfo::kBits: sequence->AddAction( WriteBasicTypeGenericLoop<BitsMarker>, new TConfiguration(info,i,compinfo,offset) ); break;
3122  if (element->GetFactor() != 0) {
3123  sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<float> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
3124  } else {
3125  Int_t nbits = (Int_t)element->GetXmin();
3126  if (!nbits) nbits = 12;
3127  sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<float> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
3128  }
3129  break;
3130  }
3132  if (element->GetFactor() != 0) {
3133  sequence->AddAction( GenericLooper<WriteBasicType_WithFactor<double> >, new TConfWithFactor(info,i,compinfo,offset,element->GetFactor(),element->GetXmin()) );
3134  } else {
3135  Int_t nbits = (Int_t)element->GetXmin();
3136  if (!nbits) {
3137  sequence->AddAction( GenericLooper<ConvertBasicType<float,double> >, new TConfiguration(info,i,compinfo,offset) );
3138  } else {
3139  sequence->AddAction( GenericLooper<WriteBasicType_NoFactor<double> >, new TConfNoFactor(info,i,compinfo,offset,nbits) );
3140  }
3141  }
3142  break;
3143  }
3144  case TVirtualStreamerInfo::kTNamed: sequence->AddAction( GenericLooper<WriteTNamed >, new TConfiguration(info,i,compinfo,offset) ); break;
3145  // Idea: We should calculate the CanIgnoreTObjectStreamer here and avoid calling the
3146  // Streamer alltogether.
3147  case TVirtualStreamerInfo::kTObject: sequence->AddAction( GenericLooper<WriteTObject >, new TConfiguration(info,i,compinfo,offset) ); break;
3148  case TVirtualStreamerInfo::kTString: sequence->AddAction( GenericLooper<WriteTString >, new TConfiguration(info,i,compinfo,offset) ); break;
3149  default:
3150  sequence->AddAction( GenericCollectionWriteAction, new TConfigSTL(info,i,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
3151  break;
3152  }
3153  }
3154  }
3155 #else
3157  /*|| (proxy.GetCollectionType() == ROOT::kSTLset || proxy.GetCollectionType() == ROOT::kSTLmultiset
3158  || proxy.GetCollectionType() == ROOT::kSTLmap || proxy.GetCollectionType() == ROOT::kSTLmultimap)*/ )
3159  {
3160  sequence->AddAction( GetCollectionWriteAction<VectorLooper>(info,element,oldType,i,compinfo,offset) );
3161  } else {
3162  // NOTE: TBranch::FillLeavesCollection[Member] is not yet ready to handle the sequence
3163  // as it does not create/use a TStaging as expected ... but then again it might
3164  // not be the right things to expect ...
3165  // sequence->AddAction( GetCollectionWriteAction<GenericLooper>(info,element,oldType,i,compinfo,offset) );
3166  sequence->AddAction( GenericLooper::GenericWrite, new TConfigSTL(info,i,compinfo,0 /* the offset will be used from TStreamerInfo */,0,proxy.GetCollectionClass(),0,0) );
3167  }
3168 #endif
3169  }
3170  return sequence;
3171 }
3173 {
3174  // Add the (potentially negative) delta to all the configuration's offset. This is used by
3175  // TBranchElement in the case of split sub-object.
3176 
3177  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3178  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3179  iter != end;
3180  ++iter)
3181  {
3182  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3183  iter->fConfiguration->AddToOffset(delta);
3184  }
3185 }
3186 
3188 {
3189  // Create a copy of this sequence.
3190 
3191  TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,fActions.size());
3192 
3193  sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
3194 
3195  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3196  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3197  iter != end;
3198  ++iter)
3199  {
3200  TConfiguration *conf = iter->fConfiguration->Copy();
3201  sequence->AddAction( iter->fAction, conf );
3202  }
3203  return sequence;
3204 }
3205 
3207 {
3208  // Create a sequence containing the subset of the action corresponding to the SteamerElement whose ids is contained in the vector.
3209  // 'offset' is the location of this 'class' within the object (address) that will be passed to ReadBuffer when using this sequence.
3210 
3211  TStreamerInfoActions::TActionSequence *sequence = new TStreamerInfoActions::TActionSequence(fStreamerInfo,element_ids.size());
3212 
3213  sequence->fLoopConfig = fLoopConfig ? fLoopConfig->Copy() : 0;
3214 
3215  for(UInt_t id = 0; id < element_ids.size(); ++id) {
3216  if ( element_ids[id] < 0 ) {
3217  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3218  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3219  iter != end;
3220  ++iter)
3221  {
3222  TConfiguration *conf = iter->fConfiguration->Copy();
3223  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3224  conf->AddToOffset(offset);
3225  sequence->AddAction( iter->fAction, conf );
3226  }
3227  } else {
3228  TStreamerInfoActions::ActionContainer_t::iterator end = fActions.end();
3229  for(TStreamerInfoActions::ActionContainer_t::iterator iter = fActions.begin();
3230  iter != end;
3231  ++iter) {
3232  if ( iter->fConfiguration->fElemId == (UInt_t)element_ids[id] ) {
3233  TConfiguration *conf = iter->fConfiguration->Copy();
3234  if (!iter->fConfiguration->fInfo->GetElements()->At(iter->fConfiguration->fElemId)->TestBit(TStreamerElement::kCache))
3235  conf->AddToOffset(offset);
3236  sequence->AddAction( iter->fAction, conf );
3237  }
3238  }
3239  }
3240  }
3241  return sequence;
3242 }
3243 
3244 #if !defined(R__WIN32) && !defined(_AIX)
3245 
3246 #include <dlfcn.h>
3247 
3248 #endif
3249 
3250 typedef void (*voidfunc)();
3251 static const char *R__GetSymbolName(voidfunc func)
3252 {
3253 #if defined(R__WIN32) || defined(__CYGWIN__) || defined(_AIX)
3254  return "not available on this platform";
3255 #if 0
3256  MEMORY_BASIC_INFORMATION mbi;
3257  if (!VirtualQuery (func, &mbi, sizeof (mbi)))
3258  {
3259  return 0;
3260  }
3261 
3262  HMODULE hMod = (HMODULE) mbi.AllocationBase;
3263  static char moduleName[MAX_PATH];
3264 
3265  if (!GetModuleFileNameA (hMod, moduleName, sizeof (moduleName)))
3266  {
3267  return 0;
3268  }
3269  return moduleName;
3270 #endif
3271 #else
3272  Dl_info info;
3273  if (dladdr((void*)func,&info)==0) {
3274  // Not in a known share library, let's give up
3275  return "name not found";
3276  } else {
3277  //fprintf(stdout,"Found address in %s\n",info.dli_fname);
3278  return info.dli_sname;
3279  }
3280 #endif
3281 }
3282 
3284 {
3285  // Add the (potentially negative) delta to all the configuration's offset. This is used by
3286  // TTBranchElement in the case of split sub-object.
3287  // If opt contains 'func', also print the (mangled) name of the function that will be executed.
3288 
3289  if (fLoopConfig) {
3290  fLoopConfig->Print();
3291  }
3292  TStreamerInfoActions::ActionContainer_t::const_iterator end = fActions.end();
3293  for(TStreamerInfoActions::ActionContainer_t::const_iterator iter = fActions.begin();
3294  iter != end;
3295  ++iter)
3296  {
3297  iter->fConfiguration->Print();
3298  if (strstr(opt,"func")) {
3299  printf("StreamerInfoAction func: %s\n",R__GetSymbolName((voidfunc)iter->fAction));
3300  }
3301  }
3302 }
3303 
3304 
const int ndata
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:229
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:47
virtual void PrintDebug(TBuffer &buffer, void *object) const
void(* DeleteIterator_t)(void *iter)
void SetBufferOffset(Int_t offset=0)
Definition: TBuffer.h:90
virtual Int_t GetCollectionType() const =0
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:329
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:39
virtual Int_t GetProperties() const
float xmin
Definition: THbookFile.cxx:93
TClass * fNewClass
Not Owned.
Definition: TStreamerInfo.h:62
virtual void * Allocate(UInt_t n, Bool_t forceDelete)=0
TVirtualStreamerInfo * fInfo
TStreamerInfo form which the action is derived.
static Vc_ALWAYS_INLINE int_v min(const int_v &x, const int_v &y)
Definition: vector.h:433
static void AddReadConvertAction(TStreamerInfoActions::TActionSequence *sequence, Int_t newtype, TConfiguration *conf)
Version_t fOldVersion
! Version of the TStreamerInfo object read from the file
static TConfiguredAction GetConvertCollectionReadActionFrom(Int_t newtype, TConfiguration *conf)
virtual TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Int_t version)=0
Int_t GetOffset() const
void AddReadMemberWiseVecPtrAction(TStreamerInfoActions::TActionSequence *readSequence, Int_t index, TCompInfo *compinfo)
Add a read action for the given element.
const char * GetTypeName() const
TStreamerInfoActions::TActionSequence * fWriteMemberWiseVecPtr
! List of write action resulting from the compilation for use in member wise streaming.
short Version_t
Definition: RtypesCore.h:61
Double_t GetXmin() const
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
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'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
tuple offset
Definition: tree.py:93
void AddAction(action_t action, TConfiguration *conf)
static void * Next(void *iter, const void *end)
R__EXTERN TVirtualMutex * gInterpreterMutex
Definition: TInterpreter.h:46
T ReadBuffer(TBufferFile *buf)
One of the template functions used to read objects from messages.
Definition: MPSendRecv.h:146
#define assert(cond)
Definition: unittest.h:542
unsigned short UShort_t
Definition: RtypesCore.h:36
static TConfiguredAction GetNumericCollectionReadAction(Int_t type, TConfigSTL *conf)
INLINE_TEMPLATE_ARGS Int_t ReadBasicType< BitsMarker >(TBuffer &buf, void *addr, const TConfiguration *config)
INLINE_TEMPLATE_ARGS Int_t ReadBasicType_NoFactor(TBuffer &buf, void *addr, const TConfiguration *config)
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:42
INLINE_TEMPLATE_ARGS Int_t ReadTObject(TBuffer &buf, void *addr, const TConfiguration *config)
#define R__ASSERT(e)
Definition: TError.h:98
TClass * GetNewClass() const
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
#define gROOT
Definition: TROOT.h:344
void AddWriteAction(TStreamerInfoActions::TActionSequence *writeSequence, Int_t index, TCompInfo *compinfo)
UInt_t fElemId
Identifier of the TStreamerElement.
virtual Int_t GetSize() const
Returns size of this element in bytes.
Basic string class.
Definition: TString.h:137
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
virtual TVirtualArray * PeekDataCache() const
Return the 'current' data cache area from the list of area to be used for temporarily store 'missing'...
Definition: TBuffer.cxx:338
Cache the value in memory than is not part of the object but is accessible via a SchemaRule.
Int_t fNdata
!number of optimized elements
virtual Bool_t IsBase() const
Return kTRUE if the element represent a base class.
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
INLINE_TEMPLATE_ARGS Int_t ReadTString(TBuffer &buf, void *addr, const TConfiguration *config)
virtual EDataType GetType() const =0
void *(* CopyIterator_t)(void *dest, const void *source)
Double_t GetFactor() const
INLINE_TEMPLATE_ARGS void ReadArraySTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
TCompInfo ** fCompFull
![fElements->GetEntries()]
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:732
static TActionSequence * CreateReadMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by '...
virtual TClass * GetCollectionClass() const
virtual void ReadInt(Int_t &i)=0
TVirtualCollectionProxy::Next_t Next_t
TActionSequence * CreateSubSequence(const std::vector< Int_t > &element_ids, size_t offset)
void ComputeSize()
Compute total size of all persistent elements of the class.
TStreamerInfoActions::TActionSequence * fReadMemberWise
! List of read action resulting from the compilation for use in member wise streaming.
TTree * T
const char * Data() const
Definition: TString.h:349
INLINE_TEMPLATE_ARGS void ReadSTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
Int_t fSize
!size of the persistent class
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)
Double_t x[n]
Definition: legend1.C:17
virtual TProcessID * ReadProcessID(UShort_t pidf)=0
Return the current Process-ID.
Definition: TBuffer.cxx:311
void Class()
Definition: Class.C:29
void(* voidfunc)()
void Init(TClassEdit::TInterpreterLookupHelper *helper)
Definition: TClassEdit.cxx:118
std::map< std::string, std::string >::const_iterator iter
Definition: TAlienJob.cxx:54
Int_t WriteLoopInvalid(TBuffer &, void *, const void *, const TConfiguration *config)
if(pyself &&pyself!=Py_None)
TMemberStreamer * fStreamer
Not Owned.
Definition: TStreamerInfo.h:64
Int_t fNfulldata
!number of elements
TStreamerInfoActions::TActionSequence * fReadObjectWise
! List of read action resulting from the compilation.
virtual TLoopConfiguration * Copy()=0
TClass * GetClass() const
A TProcessID identifies a ROOT job in a unique way in time and space.
Definition: TProcessID.h:34
XFontStruct * id
Definition: TGX11.cxx:108
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
Int_t GetArrayDim() const
virtual CreateIterators_t GetFunctionCreateIterators(Bool_t read=kTRUE)=0
void PrintDebug(TBuffer &buffer, void *object) const
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:743
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)
TClass * fClass
!pointer to class
TObjArray * fElements
Array of TStreamerElements.
void ls(Option_t *option="") const
List the TStreamerElement list and also the precomputed tables if option contains the string "incOrig...
virtual void AddAtAndExpand(TObject *obj, Int_t idx)
Add object at position idx.
Definition: TObjArray.cxx:222
Double_t length(const TVector2 &v)
Definition: CsgOps.cxx:347
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)
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:4256
virtual Int_t ApplySequence(const TStreamerInfoActions::TActionSequence &sequence, void *object)=0
Int_t fOffset
Offset within the object.
virtual void ReadFastArrayWithFactor(Float_t *ptr, Int_t n, Double_t factor, Double_t minvalue)=0
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:187
virtual Bool_t HasPointers() const =0
char * Strip(const char *str, char c= ' ')
Strip leading and trailing c (blanks by default) from a string.
Definition: TString.cxx:2464
static TActionSequence * CreateWriteMemberWiseActions(TVirtualStreamerInfo *info, TVirtualCollectionProxy &proxy)
Create the bundle of the actions necessary for the streaming memberwise of the content described by '...
virtual void ReadFastArrayFloat16(Float_t *f, Int_t n, TStreamerElement *ele=0)=0
unsigned int UInt_t
Definition: RtypesCore.h:42
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:173
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
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:81
void Print(Option_t *="") const
This method must be overridden when a class wants to print itself.
TStreamerInfoActions::TActionSequence * GetReadMemberWiseActions(Bool_t forCollection)
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseStreamer(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t, UInt_t)
static Bool_t CanOptimize()
static function returning true if optimization can be on
void Warning(const char *location, const char *msgfmt,...)
INLINE_TEMPLATE_ARGS Int_t ReadBasicType(TBuffer &buf, void *addr, const TConfiguration *config)
TClass * fClass
Not Owned.
Definition: TStreamerInfo.h:61
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)
TCompInfo * fComp
![fNslots with less than fElements->GetEntries()*1.5 used] Compiled info
TStreamerInfoActions::TActionSequence * fWriteMemberWise
! List of write action resulting from the compilation for use in member wise streaming.
PyObject * fType
TStreamerElement * fElem
Not Owned.
Definition: TStreamerInfo.h:59
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
virtual Int_t GetSize() const
Definition: TCollection.h:95
void HandleReferencedTObject(TBuffer &buf, void *addr, const TConfiguration *config)
void Copy(void *source, void *dest)
#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
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
double Double_t
Definition: RtypesCore.h:55
virtual TObjArray * GetElements() const =0
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
void(* CreateIterators_t)(void *collection, void **begin_arena, void **end_arena, TVirtualCollectionProxy *proxy)
Int_t fNslots
!total numbrer of slots in fComp.
TStreamerInfoActions::TActionSequence * fReadMemberWiseVecPtr
! List of read action resulting from the compilation for use in member wise streaming.
TStreamerInfoActions::TActionSequence * fWriteObjectWise
! List of write action resulting from the compilation.
INLINE_TEMPLATE_ARGS Int_t UseCache(TBuffer &b, void *addr, const TConfiguration *conf)
int type
Definition: TGX11.cxx:120
ClassImp(TMCParticle) void TMCParticle printf(": p=(%7.3f,%7.3f,%9.3f) ;", fPx, fPy, fPz)
static const Int_t kRegrouped
void *(* Next_t)(void *iter, const void *end)
double func(double *x, double *p)
Definition: stressTF1.cxx:213
Int_t fNVirtualInfoLoc
! Number of virtual info location to update.
Int_t GetNewType() const
#define R__LOCKGUARD(mutex)
Int_t GetEntries() const
Return the number of objects in array (i.e.
Definition: TObjArray.cxx:494
static TConfiguredAction GetConvertCollectionReadAction(Int_t oldtype, Int_t newtype, TConfiguration *conf)
TMemberStreamer * GetStreamer() const
Return the local streamer object.
void Compile()
loop on the TStreamerElement list regroup members with same type Store predigested information into l...
const char * GetErrorMessage() const
virtual CopyIterator_t GetFunctionCopyIterator(Bool_t read=kTRUE)=0
TClassRef fClass
Definition: TVirtualArray.h:28
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:433
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2730
Mother of all ROOT objects.
Definition: TObject.h:58
virtual UInt_t Size() const =0
virtual ULong_t GetMethod() const
typedef void((*Func_t)())
Int_t fNumber
!Unique identifier
Definition: TStreamerInfo.h:99
const int increment
INLINE_TEMPLATE_ARGS void ReadSTLObjectWiseFastArrayV2(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers, UInt_t start)
void GetSequenceType(TString &type) const
Fill type with the string representation of sequence information including 'cached','repeat','write' or 'nodelete'.
INLINE_TEMPLATE_ARGS Int_t ReadTNamed(TBuffer &buf, void *addr, const TConfiguration *config)
char * GetObjectAt(UInt_t ind) const
Definition: TVirtualArray.h:38
Int_t Length() const
Definition: TBuffer.h:96
INLINE_TEMPLATE_ARGS void ReadArraySTLMemberWiseChangedClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
static const char * R__GetSymbolName(voidfunc func)
virtual Bool_t HasCounter() const
Int_t GetType() const
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
INLINE_TEMPLATE_ARGS Int_t UseCacheVectorPtrLoop(TBuffer &b, void *start, const void *end, const TConfiguration *conf)
TCompInfo ** fCompOpt
![fNdata]
void(* DeleteTwoIterators_t)(void *begin, void *end)
Int_t GenericReadAction(TBuffer &buf, void *addr, const TConfiguration *config)
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
Abstract Interface class describing Streamer information for one class.
const Bool_t kTRUE
Definition: Rtypes.h:91
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.
TObject * obj
Base class of the Configurations.
UInt_t fLength
Number of element in a fixed length array.
const Int_t n
Definition: legend1.C:16
Double_t GetXmax() const
INLINE_TEMPLATE_ARGS void ReadSTLMemberWiseSameClass(TBuffer &buf, void *addr, const TConfiguration *conf, Version_t vers)
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5243
TStreamerInfoActions::TActionSequence * GetWriteMemberWiseActions(Bool_t forCollection)
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0
Int_t GetArrayLength() const
TCompInfo_t * fCompInfo
Access to compiled information (for legacy code)
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904