// @(#)root/meta:$Id$
// Author: Rene Brun   05/02/2007

/*************************************************************************
 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TVirtualStreamerInfo
#define ROOT_TVirtualStreamerInfo


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVirtualStreamerInfo   Abstract Interface class                      //
//                                                                      //
// Abstract Interface describing Streamer information for one class.    //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TNamed
#include "TNamed.h"
#endif

#ifndef ROOT_ESTLType
#include "ESTLType.h"
#endif

class TFile;
class TClass;
class TObjArray;
class TStreamerElement;
class TStreamerBasicType;
class TVirtualCollectionProxy;
class TClassStreamer;
namespace ROOT { class TCollectionProxyInfo; }

class TVirtualStreamerInfo : public TNamed {

protected:
   Bool_t              fOptimized : 1;     //! true if the StreamerInfo has been optimized
   Bool_t              fIsBuilt : 1;       //! true if the StreamerInfo has been 'built' (i.e. has all the StreamerElements it should have)
   std::atomic<Bool_t> fIsCompiled;        //! true if the StreamerInfo has been compiled (i.e. fully built, ready to use for streaming).

protected:
   static  Bool_t    fgCanDelete;        //True if ReadBuffer can delete object
   static  Bool_t    fgOptimize;         //True if optimization on
   static  Bool_t    fgStreamMemberWise; //True if the collections are to be stream "member-wise" (when possible).
   static TVirtualStreamerInfo  *fgInfoFactory;

   TVirtualStreamerInfo(const TVirtualStreamerInfo& info);
   TVirtualStreamerInfo& operator=(const TVirtualStreamerInfo&);

   void  ResetIsCompiled() {
      fIsCompiled = kFALSE;
      ResetBit(kIsCompiled); /* for backward compatibility */
   }
   void  SetIsCompiled() {
      fIsCompiled = kTRUE;
      SetBit(kIsCompiled); /* for backward compatibility */
   }

public:

   //status bits
   enum { kCannotOptimize        = BIT(12),
          kIgnoreTObjectStreamer = BIT(13),  // eventhough BIT(13) is taken up by TObject (to preserve forward compatibility)
          kRecovered             = BIT(14),
          kNeedCheck             = BIT(15),
          kIsCompiled            = BIT(16),
          kBuildOldUsed          = BIT(17),
          kBuildRunning          = BIT(18)
   };

   enum EReadWrite {
      kBase        =  0,  kOffsetL = 20,  kOffsetP = 40,  kCounter =  6,  kCharStar = 7,
      kChar        =  1,  kShort   =  2,  kInt     =  3,  kLong    =  4,  kFloat    = 5,
      kDouble      =  8,  kDouble32=  9,
      kUChar       = 11,  kUShort  = 12,  kUInt    = 13,  kULong   = 14,  kBits     = 15,
      kLong64      = 16,  kULong64 = 17,  kBool    = 18,  kFloat16 = 19,
      kObject      = 61,  kAny     = 62,  kObjectp = 63,  kObjectP = 64,  kTString  = 65,
      kTObject     = 66,  kTNamed  = 67,  kAnyp    = 68,  kAnyP    = 69,  kAnyPnoVT = 70,
      kSTLp        = 71,
      kSkip        = 100, kSkipL = 120, kSkipP   = 140,
      kConv        = 200, kConvL = 220, kConvP   = 240,
      kSTL         = ROOT::kSTLany /* 300 */,
      kSTLstring   = ROOT::kSTLstring /* 365 */,
      kStreamer    = 500, kStreamLoop = 501,
      kCache       = 600,  // Cache the value in memory than is not part of the object but is accessible via a SchemaRule
      kArtificial  = 1000,
      kCacheNew    = 1001,
      kCacheDelete = 1002,
      kNeedObjectForVirtualBaseClass = 99997,
      kMissing     = 99999
   };

// Some comments about EReadWrite
// kBase    : base class element
// kOffsetL : fixed size array
// kOffsetP : pointer to object
// kCounter : counter for array size
// kCharStar: pointer to array of char
// kBits    : TObject::fBits in case of a referenced object
// kObject  : Class  derived from TObject
// kObjectp : Class* derived from TObject and with    comment field //->Class
// kObjectP : Class* derived from TObject and with NO comment field //->Class
// kAny     : Class  not derived from TObject
// kAnyp    : Class* not derived from TObject with    comment field //->Class
// kAnyP    : Class* not derived from TObject with NO comment field //->Class
// kAnyPnoVT: Class* not derived from TObject with NO comment field //->Class and Class has NO virtual table
// kSTLp    : Pointer to STL container.
// kTString : TString, special case
// kTObject : TObject, special case
// kTNamed  : TNamed , special case



   TVirtualStreamerInfo();
   TVirtualStreamerInfo(TClass * /*cl*/);
   virtual            ~TVirtualStreamerInfo();
   virtual void        Build() = 0;
   virtual void        BuildCheck(TFile *file = 0) = 0;
   virtual void        BuildEmulated(TFile *file) = 0;
   virtual void        BuildOld() = 0;
   virtual Bool_t      BuildFor( const TClass *cl ) = 0;
   virtual void        CallShowMembers(const void* obj, TMemberInspector &insp, Bool_t isTransient) const = 0;
   virtual void        Clear(Option_t *) = 0;
   virtual Bool_t      CompareContent(TClass *cl,TVirtualStreamerInfo *info, Bool_t warn, Bool_t complete, TFile *file) = 0;
   virtual void        Compile() = 0;
   virtual void        ForceWriteInfo(TFile *file, Bool_t force=kFALSE) = 0;
   virtual Int_t       GenerateHeaderFile(const char *dirname, const TList *subClasses = 0, const TList *extrainfos = 0) = 0;
   virtual TClass     *GetActualClass(const void *obj) const = 0;
   virtual TClass     *GetClass() const  = 0;
   virtual UInt_t      GetCheckSum() const = 0;
   virtual Int_t       GetClassVersion() const = 0;
   virtual TStreamerElement *GetElem(Int_t id) const = 0;
   virtual TStreamerElement *GetElement(Int_t id) const = 0;
   virtual TObjArray  *GetElements() const = 0;
   virtual Int_t       GetOffset(const char *) const = 0;
   virtual Int_t       GetOffset(Int_t id) const = 0;
   virtual Int_t       GetElementOffset(Int_t id) const = 0;
   virtual Version_t   GetOldVersion() const = 0;
   virtual Int_t       GetOnFileClassVersion() const = 0;
   virtual Int_t       GetNumber()  const = 0;
   virtual Int_t       GetSize()    const = 0;
   virtual TStreamerElement *GetStreamerElement(const char*datamember, Int_t& offset) const = 0;
           Bool_t      IsBuilt() const { return fIsBuilt; }
           Bool_t      IsCompiled() const { return fIsCompiled; }
           Bool_t      IsOptimized() const { return fOptimized; }
           Int_t       IsRecovered() const { return TestBit(kRecovered); }
   virtual void        ls(Option_t *option="") const = 0;
   virtual TVirtualStreamerInfo *NewInfo(TClass *cl) = 0;
   virtual void       *New(void *obj = 0) = 0;
   virtual void       *NewArray(Long_t nElements, void* ary = 0) = 0;
   virtual void        Destructor(void* p, Bool_t dtorOnly = kFALSE) = 0;
   virtual void        DeleteArray(void* p, Bool_t dtorOnly = kFALSE) = 0;

   virtual void        SetCheckSum(UInt_t checksum) = 0;
   virtual void        SetClass(TClass *cl) = 0;
   virtual void        SetClassVersion(Int_t vers) = 0;
   static  Bool_t      SetStreamMemberWise(Bool_t enable = kTRUE);
   virtual void        TagFile(TFile *fFile) = 0;
   virtual void        Update(const TClass *oldClass, TClass *newClass) = 0;

   static const char         *GetElementCounterStart(const char *dmTitle);
   static TStreamerBasicType *GetElementCounter(const char *countName, TClass *cl);

   static Bool_t       CanOptimize();
   static Bool_t       GetStreamMemberWise();
   static void         Optimize(Bool_t opt=kTRUE);
   static Bool_t       CanDelete();
   static void         SetCanDelete(Bool_t opt=kTRUE);
   static void         SetFactory(TVirtualStreamerInfo *factory);

   virtual TVirtualCollectionProxy *GenEmulatedProxy(const char* class_name, Bool_t silent) = 0;
   virtual TClassStreamer *GenEmulatedClassStreamer(const char* class_name, Bool_t silent) = 0;
   virtual TVirtualCollectionProxy *GenExplicitProxy( const ::ROOT::TCollectionProxyInfo &info, TClass *cl ) = 0;
   virtual TClassStreamer *GenExplicitClassStreamer( const ::ROOT::TCollectionProxyInfo &info, TClass *cl ) = 0;
   static TVirtualStreamerInfo *Factory();

   //WARNING this class version must be the same as TStreamerInfo
   ClassDef(TVirtualStreamerInfo,6)  //Abstract Interface describing Streamer information for one class
};

#endif
 TVirtualStreamerInfo.h:1
 TVirtualStreamerInfo.h:2
 TVirtualStreamerInfo.h:3
 TVirtualStreamerInfo.h:4
 TVirtualStreamerInfo.h:5
 TVirtualStreamerInfo.h:6
 TVirtualStreamerInfo.h:7
 TVirtualStreamerInfo.h:8
 TVirtualStreamerInfo.h:9
 TVirtualStreamerInfo.h:10
 TVirtualStreamerInfo.h:11
 TVirtualStreamerInfo.h:12
 TVirtualStreamerInfo.h:13
 TVirtualStreamerInfo.h:14
 TVirtualStreamerInfo.h:15
 TVirtualStreamerInfo.h:16
 TVirtualStreamerInfo.h:17
 TVirtualStreamerInfo.h:18
 TVirtualStreamerInfo.h:19
 TVirtualStreamerInfo.h:20
 TVirtualStreamerInfo.h:21
 TVirtualStreamerInfo.h:22
 TVirtualStreamerInfo.h:23
 TVirtualStreamerInfo.h:24
 TVirtualStreamerInfo.h:25
 TVirtualStreamerInfo.h:26
 TVirtualStreamerInfo.h:27
 TVirtualStreamerInfo.h:28
 TVirtualStreamerInfo.h:29
 TVirtualStreamerInfo.h:30
 TVirtualStreamerInfo.h:31
 TVirtualStreamerInfo.h:32
 TVirtualStreamerInfo.h:33
 TVirtualStreamerInfo.h:34
 TVirtualStreamerInfo.h:35
 TVirtualStreamerInfo.h:36
 TVirtualStreamerInfo.h:37
 TVirtualStreamerInfo.h:38
 TVirtualStreamerInfo.h:39
 TVirtualStreamerInfo.h:40
 TVirtualStreamerInfo.h:41
 TVirtualStreamerInfo.h:42
 TVirtualStreamerInfo.h:43
 TVirtualStreamerInfo.h:44
 TVirtualStreamerInfo.h:45
 TVirtualStreamerInfo.h:46
 TVirtualStreamerInfo.h:47
 TVirtualStreamerInfo.h:48
 TVirtualStreamerInfo.h:49
 TVirtualStreamerInfo.h:50
 TVirtualStreamerInfo.h:51
 TVirtualStreamerInfo.h:52
 TVirtualStreamerInfo.h:53
 TVirtualStreamerInfo.h:54
 TVirtualStreamerInfo.h:55
 TVirtualStreamerInfo.h:56
 TVirtualStreamerInfo.h:57
 TVirtualStreamerInfo.h:58
 TVirtualStreamerInfo.h:59
 TVirtualStreamerInfo.h:60
 TVirtualStreamerInfo.h:61
 TVirtualStreamerInfo.h:62
 TVirtualStreamerInfo.h:63
 TVirtualStreamerInfo.h:64
 TVirtualStreamerInfo.h:65
 TVirtualStreamerInfo.h:66
 TVirtualStreamerInfo.h:67
 TVirtualStreamerInfo.h:68
 TVirtualStreamerInfo.h:69
 TVirtualStreamerInfo.h:70
 TVirtualStreamerInfo.h:71
 TVirtualStreamerInfo.h:72
 TVirtualStreamerInfo.h:73
 TVirtualStreamerInfo.h:74
 TVirtualStreamerInfo.h:75
 TVirtualStreamerInfo.h:76
 TVirtualStreamerInfo.h:77
 TVirtualStreamerInfo.h:78
 TVirtualStreamerInfo.h:79
 TVirtualStreamerInfo.h:80
 TVirtualStreamerInfo.h:81
 TVirtualStreamerInfo.h:82
 TVirtualStreamerInfo.h:83
 TVirtualStreamerInfo.h:84
 TVirtualStreamerInfo.h:85
 TVirtualStreamerInfo.h:86
 TVirtualStreamerInfo.h:87
 TVirtualStreamerInfo.h:88
 TVirtualStreamerInfo.h:89
 TVirtualStreamerInfo.h:90
 TVirtualStreamerInfo.h:91
 TVirtualStreamerInfo.h:92
 TVirtualStreamerInfo.h:93
 TVirtualStreamerInfo.h:94
 TVirtualStreamerInfo.h:95
 TVirtualStreamerInfo.h:96
 TVirtualStreamerInfo.h:97
 TVirtualStreamerInfo.h:98
 TVirtualStreamerInfo.h:99
 TVirtualStreamerInfo.h:100
 TVirtualStreamerInfo.h:101
 TVirtualStreamerInfo.h:102
 TVirtualStreamerInfo.h:103
 TVirtualStreamerInfo.h:104
 TVirtualStreamerInfo.h:105
 TVirtualStreamerInfo.h:106
 TVirtualStreamerInfo.h:107
 TVirtualStreamerInfo.h:108
 TVirtualStreamerInfo.h:109
 TVirtualStreamerInfo.h:110
 TVirtualStreamerInfo.h:111
 TVirtualStreamerInfo.h:112
 TVirtualStreamerInfo.h:113
 TVirtualStreamerInfo.h:114
 TVirtualStreamerInfo.h:115
 TVirtualStreamerInfo.h:116
 TVirtualStreamerInfo.h:117
 TVirtualStreamerInfo.h:118
 TVirtualStreamerInfo.h:119
 TVirtualStreamerInfo.h:120
 TVirtualStreamerInfo.h:121
 TVirtualStreamerInfo.h:122
 TVirtualStreamerInfo.h:123
 TVirtualStreamerInfo.h:124
 TVirtualStreamerInfo.h:125
 TVirtualStreamerInfo.h:126
 TVirtualStreamerInfo.h:127
 TVirtualStreamerInfo.h:128
 TVirtualStreamerInfo.h:129
 TVirtualStreamerInfo.h:130
 TVirtualStreamerInfo.h:131
 TVirtualStreamerInfo.h:132
 TVirtualStreamerInfo.h:133
 TVirtualStreamerInfo.h:134
 TVirtualStreamerInfo.h:135
 TVirtualStreamerInfo.h:136
 TVirtualStreamerInfo.h:137
 TVirtualStreamerInfo.h:138
 TVirtualStreamerInfo.h:139
 TVirtualStreamerInfo.h:140
 TVirtualStreamerInfo.h:141
 TVirtualStreamerInfo.h:142
 TVirtualStreamerInfo.h:143
 TVirtualStreamerInfo.h:144
 TVirtualStreamerInfo.h:145
 TVirtualStreamerInfo.h:146
 TVirtualStreamerInfo.h:147
 TVirtualStreamerInfo.h:148
 TVirtualStreamerInfo.h:149
 TVirtualStreamerInfo.h:150
 TVirtualStreamerInfo.h:151
 TVirtualStreamerInfo.h:152
 TVirtualStreamerInfo.h:153
 TVirtualStreamerInfo.h:154
 TVirtualStreamerInfo.h:155
 TVirtualStreamerInfo.h:156
 TVirtualStreamerInfo.h:157
 TVirtualStreamerInfo.h:158
 TVirtualStreamerInfo.h:159
 TVirtualStreamerInfo.h:160
 TVirtualStreamerInfo.h:161
 TVirtualStreamerInfo.h:162
 TVirtualStreamerInfo.h:163
 TVirtualStreamerInfo.h:164
 TVirtualStreamerInfo.h:165
 TVirtualStreamerInfo.h:166
 TVirtualStreamerInfo.h:167
 TVirtualStreamerInfo.h:168
 TVirtualStreamerInfo.h:169
 TVirtualStreamerInfo.h:170
 TVirtualStreamerInfo.h:171
 TVirtualStreamerInfo.h:172
 TVirtualStreamerInfo.h:173
 TVirtualStreamerInfo.h:174
 TVirtualStreamerInfo.h:175
 TVirtualStreamerInfo.h:176
 TVirtualStreamerInfo.h:177
 TVirtualStreamerInfo.h:178
 TVirtualStreamerInfo.h:179
 TVirtualStreamerInfo.h:180
 TVirtualStreamerInfo.h:181
 TVirtualStreamerInfo.h:182
 TVirtualStreamerInfo.h:183
 TVirtualStreamerInfo.h:184
 TVirtualStreamerInfo.h:185
 TVirtualStreamerInfo.h:186
 TVirtualStreamerInfo.h:187
 TVirtualStreamerInfo.h:188