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

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TEmulatedMapProxy
//
// Streamer around an arbitrary container, which implements basic
// functionality and iteration.
//
// 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.
//
//////////////////////////////////////////////////////////////////////////

#include "TEmulatedMapProxy.h"
#include "TClassEdit.h"
#include "TStreamerInfo.h"
#include "TError.h"

TEmulatedMapProxy::TEmulatedMapProxy(const TEmulatedMapProxy& copy)
   : TEmulatedCollectionProxy(copy)
{
   // copy constructor
   if ( !(fSTL_type == ROOT::kSTLmap || fSTL_type == ROOT::kSTLmultimap) )  {
      Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
   }
}

TEmulatedMapProxy::TEmulatedMapProxy(const char* cl_name, Bool_t silent)
   : TEmulatedCollectionProxy(cl_name, silent)
{
   // Build a Streamer for an emulated vector whose type is 'name'.
   if ( !(fSTL_type == ROOT::kSTLmap || fSTL_type == ROOT::kSTLmultimap) )  {
      Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
   }
}

TEmulatedMapProxy::~TEmulatedMapProxy()
{
   // Standard destructor.
}

TVirtualCollectionProxy* TEmulatedMapProxy::Generate() const
{
   // Virtual copy constructor.
   if ( !fClass ) Initialize(kFALSE);
   return new TEmulatedMapProxy(*this);
}

void* TEmulatedMapProxy::At(UInt_t idx)
{
   // Return the address of the value at index 'idx'.
   if ( fEnv && fEnv->fObject )   {
      PCont_t c = PCont_t(fEnv->fObject);
      return idx<(c->size()/fValDiff) ? ((char*)&(*c->begin())) + idx*fValDiff : 0;
   }
   Fatal("TEmulatedMapProxy","At> Logic error - no proxy object set.");
   return 0;
}

UInt_t TEmulatedMapProxy::Size() const
{
   // Return the current size of the container.
   if ( fEnv && fEnv->fObject )   {
      PCont_t c = PCont_t(fEnv->fObject);
      return fEnv->fSize = (c->size()/fValDiff);
   }
   Fatal("TEmulatedMapProxy","Size> Logic error - no proxy object set.");
   return 0;
}

void TEmulatedMapProxy::ReadMap(UInt_t nElements, TBuffer &b)
{
   // Map input streamer.
   Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
   UInt_t idx, loop;
   Int_t off[2] = {0, fValOffset };
   Value  *v, *val[2] = { fKey, fVal };
   StreamHelper* helper;
   float f;
   char* addr = 0;
   char* temp = (char*)At(0);
   for ( idx = 0; idx < nElements; ++idx )  {
      addr = temp + idx*fValDiff;
      for ( loop=0; loop<2; loop++)  {
         addr += off[loop];
         helper = (StreamHelper*)addr;
         v = val[loop];
         switch (v->fCase) {
         case kIsFundamental:  // Only handle primitives this way
         case kIsEnum:
            switch( int(v->fKind) )   {
            case kBool_t:    b >> helper->boolean;     break;
            case kChar_t:    b >> helper->s_char;      break;
            case kShort_t:   b >> helper->s_short;     break;
            case kInt_t:     b >> helper->s_int;       break;
            case kLong_t:    b >> helper->s_long;      break;
            case kLong64_t:  b >> helper->s_longlong;  break;
            case kFloat_t:   b >> helper->flt;         break;
            case kFloat16_t: b >> f;
               helper->flt = float(f);  break;
            case kDouble_t:  b >> helper->dbl;         break;
            case kBOOL_t:    b >> helper->boolean;     break;
            case kUChar_t:   b >> helper->u_char;      break;
            case kUShort_t:  b >> helper->u_short;     break;
            case kUInt_t:    b >> helper->u_int;       break;
            case kULong_t:   b >> helper->u_long;      break;
            case kULong64_t: b >> helper->u_longlong;  break;
            case kDouble32_t:b >> f;
               helper->dbl = double(f);  break;
            case kchar:
            case kNoType_t:
            case kOther_t:
               Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
            }
            break;
         case kIsClass:
            b.StreamObject(helper,v->fType);
            break;
         case kBIT_ISSTRING:
            helper->read_std_string(b);
            break;
         case kIsPointer|kIsClass:
            helper->set(b.ReadObjectAny(v->fType));
            break;
         case kIsPointer|kBIT_ISSTRING:
            helper->read_std_string_pointer(b);
            break;
         case kIsPointer|kBIT_ISTSTRING|kIsClass:
            helper->read_tstring_pointer(vsn3,b);
            break;
         }
      }
   }
}

void TEmulatedMapProxy::WriteMap(UInt_t nElements, TBuffer &b)
{
   // Map output streamer.
   Value  *v, *val[2] = { fKey, fVal };
   int    off[2]      = { 0, fValOffset };
   StreamHelper* i;
   char* addr = 0;
   char* temp = (char*)At(0);
   for (UInt_t loop, idx = 0; idx < nElements; ++idx )  {
      addr = temp + idx*fValDiff;
      for ( loop = 0; loop<2; ++loop )  {
         addr += off[loop];
         i = (StreamHelper*)addr;
         v = val[loop];
         switch (v->fCase) {
         case kIsFundamental:  // Only handle primitives this way
         case kIsEnum:
            switch( int(v->fKind) )   {
            case kBool_t:    b << i->boolean;     break;
            case kChar_t:    b << i->s_char;      break;
            case kShort_t:   b << i->s_short;     break;
            case kInt_t:     b << i->s_int;       break;
            case kLong_t:    b << i->s_long;      break;
            case kLong64_t:  b << i->s_longlong;  break;
            case kFloat_t:   b << i->flt;         break;
            case kFloat16_t: b << float(i->flt);  break;
            case kDouble_t:  b << i->dbl;         break;
            case kBOOL_t:    b << i->boolean;     break;
            case kUChar_t:   b << i->u_char;      break;
            case kUShort_t:  b << i->u_short;     break;
            case kUInt_t:    b << i->u_int;       break;
            case kULong_t:   b << i->u_long;      break;
            case kULong64_t: b << i->u_longlong;  break;
            case kDouble32_t:b << float(i->dbl);  break;
            case kchar:
            case kNoType_t:
            case kOther_t:
               Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
            }
            break;
         case kIsClass:
            b.StreamObject(i,v->fType);
            break;
         case kBIT_ISSTRING:
            TString(i->c_str()).Streamer(b);
            break;
         case kIsPointer|kIsClass:
            b.WriteObjectAny(i->ptr(),v->fType);
            break;
         case kBIT_ISSTRING|kIsPointer:
            i->write_std_string_pointer(b);
            break;
         case kBIT_ISTSTRING|kIsClass|kIsPointer:
            i->write_tstring_pointer(b);
            break;
         }
      }
   }
}

void TEmulatedMapProxy::ReadBuffer(TBuffer &b, void *obj, const TClass *onfileClass)
{
   // Read portion of the streamer.

   SetOnFileClass((TClass*)onfileClass);
   ReadBuffer(b,obj);
}

void TEmulatedMapProxy::ReadBuffer(TBuffer &b, void *obj)
{
   // Read portion of the streamer.

   TPushPop env(this,obj);
   int nElements = 0;
   b >> nElements;
   if ( fEnv->fObject )  {
      Resize(nElements,true);
   }
   if ( nElements > 0 )  {
      ReadMap(nElements, b);
   }
}

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