// @(#)root/io:$Id$
// Author: Markus Frank  28/10/04

/*************************************************************************
 * Copyright (C) 1995-2004, 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_TCollectionProxyFactory
#define ROOT_TCollectionProxyFactory

//////////////////////////////////////////////////////////////////////////
//                                                                      //
//  Small helper to save proxy environment in the event of
//  recursive calls.
//
//////////////////////////////////////////////////////////////////////////

#include <typeinfo>
#include <vector>

#ifndef ROOT_TCollectionProxyInfo
#include "TCollectionProxyInfo.h"
#endif

#ifndef ROOT_TClassStreamer
#include "TClassStreamer.h"
#endif

#ifndef ROOT_TMemberStreamer
#include "TMemberStreamer.h"
#endif

#ifndef ROOT_TGenCollectionProxy
#include "TGenCollectionProxy.h"
#endif

// Forward declarations
class TBuffer;
class TGenCollectionProxy;
class TGenCollectionStreamer;
class TVirtualCollectionProxy;
class TEmulatedCollectionProxy;

#if defined(_WIN32)
   #if _MSC_VER<1300
      #define TYPENAME
      #define R__VCXX6
   #else
      #define TYPENAME typename
   #endif
#else
   #define TYPENAME typename
#endif


/** @class TCollectionProxyFactory TCollectionProxyFactory.h cont/TCollectionProxyFactory.h
  *
  * TCollectionProxyFactory
  * Interface to collection proxy and streamer generator.
  *
  * Proxy around an arbitrary container, which implements basic
  * functionality and iteration. The purpose of this implementation
  * is to shield any generated dictionary implementation from the
  * underlying streamer/proxy implementation and only expose
  * the creation functions.
  *
  * In particular this is used to implement splitting and abstract
  * element access of any container. Access to compiled code is necessary
  * to implement the abstract iteration sequence and functionality like
  * size(), clear(), resize(). resize() may be a void operation.
  *
  * @author  M.Frank
  * @version 1.0
  */
class TCollectionProxyFactory  {
public:

   typedef TVirtualCollectionProxy Proxy_t;
#ifdef R__HPUX
   typedef const type_info&      Info_t;
#else
   typedef const std::type_info& Info_t;
#endif




   /// Generate emulated collection proxy for a given class
   static TVirtualCollectionProxy* GenEmulatedProxy(const char* class_name, Bool_t silent);

   /// Generate emulated class streamer for a given collection class
   static TClassStreamer* GenEmulatedClassStreamer(const char* class_name, Bool_t silent);

   /// Generate emulated member streamer for a given collection class
   static TMemberStreamer* GenEmulatedMemberStreamer(const char* class_name, Bool_t silent);


   /// Generate proxy from static functions
   static Proxy_t* GenExplicitProxy( const ::ROOT::TCollectionProxyInfo &info, TClass *cl );

   /// Generate proxy from template
   template <class T> static Proxy_t* GenProxy(const T &arg, TClass *cl)  {
      return GenExplicitProxy( ::ROOT::TCollectionProxyInfo::Get(arg), cl );
   }

   /// Generate streamer from static functions
   static TGenCollectionStreamer*
      GenExplicitStreamer( const ::ROOT::TCollectionProxyInfo &info, TClass *cl );

   /// Generate class streamer from static functions
   static TClassStreamer*
      GenExplicitClassStreamer( const ::ROOT::TCollectionProxyInfo &info, TClass *cl );

   /// Generate class streamer from template
   template <class T> static TClassStreamer* GenClassStreamer(const T &arg, TClass *cl)  {
      return GenExplicitClassStreamer(::ROOT::TCollectionProxyInfo::Get(arg), cl);
   }

   /// Generate member streamer from static functions
   static TMemberStreamer*
      GenExplicitMemberStreamer(const ::ROOT::TCollectionProxyInfo &info, TClass *cl);

   /// Generate member streamer from template
   template <class T> static TMemberStreamer* GenMemberStreamer(const T &arg, TClass *cl)  {
      return GenExplicitMemberStreamer(::ROOT::TCollectionProxyInfo::Get(arg), cl);
   }
};

/** @class TCollectionStreamer TCollectionProxyFactory.h cont/TCollectionProxyFactory.h
 *
 * TEmulatedClassStreamer
 *
 * Class streamer object to implement TClassStreamr functionality
 * for I/O emulation.
 *
 * @author  M.Frank
 * @version 1.0
 */
class TCollectionStreamer   {
private:
   TCollectionStreamer& operator=(const TCollectionStreamer&);   // not implemented

protected:
   TGenCollectionProxy* fStreamer;   /// Pointer to worker streamer

   /// Issue Error about invalid proxy
   void InvalidProxyError();

public:
   /// Initializing constructor
   TCollectionStreamer();
   /// Copy constructor
   TCollectionStreamer(const TCollectionStreamer& c);
   /// Standard destructor
   virtual ~TCollectionStreamer();
   /// Attach worker proxy
   void AdoptStreamer(TGenCollectionProxy* streamer);
   /// Streamer for I/O handling
   void Streamer(TBuffer &refBuffer, void *obj, int siz, TClass *onFileClass );
};

/** @class TEmulatedClassStreamer TCollectionProxy.h cont/TCollectionProxy.h
  *
  * TEmulatedClassStreamer
  *
  * Class streamer object to implement TClassStreamr functionality
  * for I/O emulation.
  *
  * @author  M.Frank
  * @version 1.0
  */
class TCollectionClassStreamer : public TClassStreamer, public TCollectionStreamer {
 protected:
   TCollectionClassStreamer &operator=(const TCollectionClassStreamer &rhs); // Not implemented.
   /// Copy constructor
   TCollectionClassStreamer(const TCollectionClassStreamer& c)
      : TClassStreamer(c), TCollectionStreamer(c)      {                        }

public:
   /// Initializing constructor
   TCollectionClassStreamer() : TClassStreamer(0)     {                        }
   /// Standard destructor
   virtual ~TCollectionClassStreamer()                {                        }
   /// Streamer for I/O handling
   virtual void operator()(TBuffer &buff, void *obj ) { Streamer(buff,obj,0,fOnFileClass); }

   virtual void Stream(TBuffer &b, void *obj, const TClass *onfileClass)
   {
      if (b.IsReading()) {
         TGenCollectionProxy *proxy = TCollectionStreamer::fStreamer;
         if (onfileClass==0 || onfileClass == proxy->GetCollectionClass()) {
            proxy->ReadBuffer(b,obj);
         } else {
            proxy->ReadBuffer(b,obj,onfileClass);
         }
      } else {
         // fStreamer->WriteBuffer(b,objp,onfileClass);
         Streamer(b,obj,0,(TClass*)onfileClass);
      }
   }
   
   /// Virtual copy constructor.
   virtual TClassStreamer *Generate() const {
      return new TCollectionClassStreamer(*this);
   }

   TGenCollectionProxy *GetXYZ() { return TCollectionStreamer::fStreamer; }

};

/** @class TCollectionMemberStreamer TCollectionProxyFactory.h cont/TCollectionProxyFactory.h
  *
  * TCollectionMemberStreamer
  *
  * Class streamer object to implement TMemberStreamer functionality
  * for I/O emulation.
  *
  * @author  M.Frank
  * @version 1.0
  */
class TCollectionMemberStreamer : public TMemberStreamer, public TCollectionStreamer {
private:
   TCollectionMemberStreamer &operator=(const TCollectionMemberStreamer &rhs); // Not implemented.
public:
   /// Initializing constructor
   TCollectionMemberStreamer() : TMemberStreamer(0) { }
   /// Copy constructor
   TCollectionMemberStreamer(const TCollectionMemberStreamer& c)
      : TMemberStreamer(c), TCollectionStreamer(c)   { }
   /// Standard destructor
   virtual ~TCollectionMemberStreamer()             { }
   /// Streamer for I/O handling
   virtual void operator()(TBuffer &buff,void *obj,Int_t siz=0)
   { Streamer(buff, obj, siz, 0); /* FIXME */ }   
};

#endif
 TCollectionProxyFactory.h:1
 TCollectionProxyFactory.h:2
 TCollectionProxyFactory.h:3
 TCollectionProxyFactory.h:4
 TCollectionProxyFactory.h:5
 TCollectionProxyFactory.h:6
 TCollectionProxyFactory.h:7
 TCollectionProxyFactory.h:8
 TCollectionProxyFactory.h:9
 TCollectionProxyFactory.h:10
 TCollectionProxyFactory.h:11
 TCollectionProxyFactory.h:12
 TCollectionProxyFactory.h:13
 TCollectionProxyFactory.h:14
 TCollectionProxyFactory.h:15
 TCollectionProxyFactory.h:16
 TCollectionProxyFactory.h:17
 TCollectionProxyFactory.h:18
 TCollectionProxyFactory.h:19
 TCollectionProxyFactory.h:20
 TCollectionProxyFactory.h:21
 TCollectionProxyFactory.h:22
 TCollectionProxyFactory.h:23
 TCollectionProxyFactory.h:24
 TCollectionProxyFactory.h:25
 TCollectionProxyFactory.h:26
 TCollectionProxyFactory.h:27
 TCollectionProxyFactory.h:28
 TCollectionProxyFactory.h:29
 TCollectionProxyFactory.h:30
 TCollectionProxyFactory.h:31
 TCollectionProxyFactory.h:32
 TCollectionProxyFactory.h:33
 TCollectionProxyFactory.h:34
 TCollectionProxyFactory.h:35
 TCollectionProxyFactory.h:36
 TCollectionProxyFactory.h:37
 TCollectionProxyFactory.h:38
 TCollectionProxyFactory.h:39
 TCollectionProxyFactory.h:40
 TCollectionProxyFactory.h:41
 TCollectionProxyFactory.h:42
 TCollectionProxyFactory.h:43
 TCollectionProxyFactory.h:44
 TCollectionProxyFactory.h:45
 TCollectionProxyFactory.h:46
 TCollectionProxyFactory.h:47
 TCollectionProxyFactory.h:48
 TCollectionProxyFactory.h:49
 TCollectionProxyFactory.h:50
 TCollectionProxyFactory.h:51
 TCollectionProxyFactory.h:52
 TCollectionProxyFactory.h:53
 TCollectionProxyFactory.h:54
 TCollectionProxyFactory.h:55
 TCollectionProxyFactory.h:56
 TCollectionProxyFactory.h:57
 TCollectionProxyFactory.h:58
 TCollectionProxyFactory.h:59
 TCollectionProxyFactory.h:60
 TCollectionProxyFactory.h:61
 TCollectionProxyFactory.h:62
 TCollectionProxyFactory.h:63
 TCollectionProxyFactory.h:64
 TCollectionProxyFactory.h:65
 TCollectionProxyFactory.h:66
 TCollectionProxyFactory.h:67
 TCollectionProxyFactory.h:68
 TCollectionProxyFactory.h:69
 TCollectionProxyFactory.h:70
 TCollectionProxyFactory.h:71
 TCollectionProxyFactory.h:72
 TCollectionProxyFactory.h:73
 TCollectionProxyFactory.h:74
 TCollectionProxyFactory.h:75
 TCollectionProxyFactory.h:76
 TCollectionProxyFactory.h:77
 TCollectionProxyFactory.h:78
 TCollectionProxyFactory.h:79
 TCollectionProxyFactory.h:80
 TCollectionProxyFactory.h:81
 TCollectionProxyFactory.h:82
 TCollectionProxyFactory.h:83
 TCollectionProxyFactory.h:84
 TCollectionProxyFactory.h:85
 TCollectionProxyFactory.h:86
 TCollectionProxyFactory.h:87
 TCollectionProxyFactory.h:88
 TCollectionProxyFactory.h:89
 TCollectionProxyFactory.h:90
 TCollectionProxyFactory.h:91
 TCollectionProxyFactory.h:92
 TCollectionProxyFactory.h:93
 TCollectionProxyFactory.h:94
 TCollectionProxyFactory.h:95
 TCollectionProxyFactory.h:96
 TCollectionProxyFactory.h:97
 TCollectionProxyFactory.h:98
 TCollectionProxyFactory.h:99
 TCollectionProxyFactory.h:100
 TCollectionProxyFactory.h:101
 TCollectionProxyFactory.h:102
 TCollectionProxyFactory.h:103
 TCollectionProxyFactory.h:104
 TCollectionProxyFactory.h:105
 TCollectionProxyFactory.h:106
 TCollectionProxyFactory.h:107
 TCollectionProxyFactory.h:108
 TCollectionProxyFactory.h:109
 TCollectionProxyFactory.h:110
 TCollectionProxyFactory.h:111
 TCollectionProxyFactory.h:112
 TCollectionProxyFactory.h:113
 TCollectionProxyFactory.h:114
 TCollectionProxyFactory.h:115
 TCollectionProxyFactory.h:116
 TCollectionProxyFactory.h:117
 TCollectionProxyFactory.h:118
 TCollectionProxyFactory.h:119
 TCollectionProxyFactory.h:120
 TCollectionProxyFactory.h:121
 TCollectionProxyFactory.h:122
 TCollectionProxyFactory.h:123
 TCollectionProxyFactory.h:124
 TCollectionProxyFactory.h:125
 TCollectionProxyFactory.h:126
 TCollectionProxyFactory.h:127
 TCollectionProxyFactory.h:128
 TCollectionProxyFactory.h:129
 TCollectionProxyFactory.h:130
 TCollectionProxyFactory.h:131
 TCollectionProxyFactory.h:132
 TCollectionProxyFactory.h:133
 TCollectionProxyFactory.h:134
 TCollectionProxyFactory.h:135
 TCollectionProxyFactory.h:136
 TCollectionProxyFactory.h:137
 TCollectionProxyFactory.h:138
 TCollectionProxyFactory.h:139
 TCollectionProxyFactory.h:140
 TCollectionProxyFactory.h:141
 TCollectionProxyFactory.h:142
 TCollectionProxyFactory.h:143
 TCollectionProxyFactory.h:144
 TCollectionProxyFactory.h:145
 TCollectionProxyFactory.h:146
 TCollectionProxyFactory.h:147
 TCollectionProxyFactory.h:148
 TCollectionProxyFactory.h:149
 TCollectionProxyFactory.h:150
 TCollectionProxyFactory.h:151
 TCollectionProxyFactory.h:152
 TCollectionProxyFactory.h:153
 TCollectionProxyFactory.h:154
 TCollectionProxyFactory.h:155
 TCollectionProxyFactory.h:156
 TCollectionProxyFactory.h:157
 TCollectionProxyFactory.h:158
 TCollectionProxyFactory.h:159
 TCollectionProxyFactory.h:160
 TCollectionProxyFactory.h:161
 TCollectionProxyFactory.h:162
 TCollectionProxyFactory.h:163
 TCollectionProxyFactory.h:164
 TCollectionProxyFactory.h:165
 TCollectionProxyFactory.h:166
 TCollectionProxyFactory.h:167
 TCollectionProxyFactory.h:168
 TCollectionProxyFactory.h:169
 TCollectionProxyFactory.h:170
 TCollectionProxyFactory.h:171
 TCollectionProxyFactory.h:172
 TCollectionProxyFactory.h:173
 TCollectionProxyFactory.h:174
 TCollectionProxyFactory.h:175
 TCollectionProxyFactory.h:176
 TCollectionProxyFactory.h:177
 TCollectionProxyFactory.h:178
 TCollectionProxyFactory.h:179
 TCollectionProxyFactory.h:180
 TCollectionProxyFactory.h:181
 TCollectionProxyFactory.h:182
 TCollectionProxyFactory.h:183
 TCollectionProxyFactory.h:184
 TCollectionProxyFactory.h:185
 TCollectionProxyFactory.h:186
 TCollectionProxyFactory.h:187
 TCollectionProxyFactory.h:188
 TCollectionProxyFactory.h:189
 TCollectionProxyFactory.h:190
 TCollectionProxyFactory.h:191
 TCollectionProxyFactory.h:192
 TCollectionProxyFactory.h:193
 TCollectionProxyFactory.h:194
 TCollectionProxyFactory.h:195
 TCollectionProxyFactory.h:196
 TCollectionProxyFactory.h:197
 TCollectionProxyFactory.h:198
 TCollectionProxyFactory.h:199
 TCollectionProxyFactory.h:200
 TCollectionProxyFactory.h:201
 TCollectionProxyFactory.h:202
 TCollectionProxyFactory.h:203
 TCollectionProxyFactory.h:204
 TCollectionProxyFactory.h:205
 TCollectionProxyFactory.h:206
 TCollectionProxyFactory.h:207
 TCollectionProxyFactory.h:208
 TCollectionProxyFactory.h:209
 TCollectionProxyFactory.h:210
 TCollectionProxyFactory.h:211
 TCollectionProxyFactory.h:212
 TCollectionProxyFactory.h:213
 TCollectionProxyFactory.h:214
 TCollectionProxyFactory.h:215
 TCollectionProxyFactory.h:216
 TCollectionProxyFactory.h:217
 TCollectionProxyFactory.h:218
 TCollectionProxyFactory.h:219
 TCollectionProxyFactory.h:220
 TCollectionProxyFactory.h:221
 TCollectionProxyFactory.h:222
 TCollectionProxyFactory.h:223
 TCollectionProxyFactory.h:224
 TCollectionProxyFactory.h:225
 TCollectionProxyFactory.h:226
 TCollectionProxyFactory.h:227
 TCollectionProxyFactory.h:228
 TCollectionProxyFactory.h:229
 TCollectionProxyFactory.h:230
 TCollectionProxyFactory.h:231
 TCollectionProxyFactory.h:232
 TCollectionProxyFactory.h:233
 TCollectionProxyFactory.h:234
 TCollectionProxyFactory.h:235
 TCollectionProxyFactory.h:236
 TCollectionProxyFactory.h:237
 TCollectionProxyFactory.h:238
 TCollectionProxyFactory.h:239
 TCollectionProxyFactory.h:240