TGenCollectionStreamer.cxx

Go to the documentation of this file.
00001 // @(#)root/io:$Id: TGenCollectionStreamer.cxx 36061 2010-10-04 16:05:51Z pcanal $
00002 // Author: Markus Frank 28/10/04
00003 
00004 /*************************************************************************
00005  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
00006  * All rights reserved.                                                  *
00007  *                                                                       *
00008  * For the licensing terms see $ROOTSYS/LICENSE.                         *
00009  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
00010  *************************************************************************/
00011 
00012 //////////////////////////////////////////////////////////////////////////
00013 //                                                                      //
00014 // TGenCollectionStreamer
00015 //
00016 // Streamer around an arbitrary container, which implements basic
00017 // functionality and iteration.
00018 //
00019 // In particular this is used to implement splitting and abstract
00020 // element access of any container. Access to compiled code is necessary
00021 // to implement the abstract iteration sequence and functionality like
00022 // size(), clear(), resize(). resize() may be a void operation.
00023 //
00024 //////////////////////////////////////////////////////////////////////////
00025 
00026 #include "TGenCollectionStreamer.h"
00027 #include "TClassEdit.h"
00028 #include "TError.h"
00029 #include "TROOT.h"
00030 #include "TStreamerInfo.h"
00031 #include "TStreamerElement.h"
00032 #include "Riostream.h"
00033 #include "TVirtualCollectionIterators.h"
00034 
00035 TGenCollectionStreamer::TGenCollectionStreamer(const TGenCollectionStreamer& copy)
00036       : TGenCollectionProxy(copy), fReadBufferFunc(&TGenCollectionStreamer::ReadBufferDefault)
00037 {
00038    // Build a Streamer for an emulated vector whose type is 'name'.
00039 }
00040 
00041 TGenCollectionStreamer::TGenCollectionStreamer(Info_t info, size_t iter_size)
00042       : TGenCollectionProxy(info, iter_size), fReadBufferFunc(&TGenCollectionStreamer::ReadBufferDefault)
00043 {
00044    // Build a Streamer for a collection whose type is described by 'collectionClass'.
00045 }
00046 
00047 TGenCollectionStreamer::TGenCollectionStreamer(const ::ROOT::TCollectionProxyInfo &info, TClass *cl)
00048       : TGenCollectionProxy(info, cl), fReadBufferFunc(&TGenCollectionStreamer::ReadBufferDefault)
00049 {
00050    // Build a Streamer for a collection whose type is described by 'collectionClass'.
00051 }
00052 
00053 TGenCollectionStreamer::~TGenCollectionStreamer()
00054 {
00055    // Standard destructor.
00056 }
00057 
00058 TVirtualCollectionProxy* TGenCollectionStreamer::Generate() const
00059 {
00060    // Virtual copy constructor.
00061    if (!fClass) Initialize();
00062    return new TGenCollectionStreamer(*this);
00063 }
00064 
00065 
00066 void TGenCollectionStreamer::ReadPrimitives(int nElements, TBuffer &b)
00067 {
00068    // Primitive input streamer.
00069    size_t len = fValDiff * nElements;
00070    char   buffer[8096];
00071    Bool_t   feed = false;
00072    void*  memory = 0;
00073    StreamHelper* itm = 0;
00074    fEnv->fSize = nElements;
00075    switch (fSTL_type)  {
00076       case TClassEdit::kVector:
00077          if (fVal->fKind != EDataType(kBOOL_t))  {
00078             fResize(fEnv->fObject,fEnv->fSize);
00079             fEnv->fIdx = 0;
00080             
00081             TVirtualVectorIterators iterators(fFunctionCreateIterators);
00082             iterators.CreateIterators(fEnv->fObject);
00083             itm = (StreamHelper*)iterators.fBegin;
00084             fEnv->fStart = itm;
00085             break;
00086          }
00087       default:
00088          feed = true;
00089          itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
00090          break;
00091    }
00092    fEnv->fStart = itm;
00093    switch (int(fVal->fKind))   {
00094       case kBool_t:
00095          b.ReadFastArray(&itm->boolean   , nElements);
00096          break;
00097       case kChar_t:
00098          b.ReadFastArray(&itm->s_char    , nElements);
00099          break;
00100       case kShort_t:
00101          b.ReadFastArray(&itm->s_short   , nElements);
00102          break;
00103       case kInt_t:
00104          b.ReadFastArray(&itm->s_int     , nElements);
00105          break;
00106       case kLong_t:
00107          b.ReadFastArray(&itm->s_long    , nElements);
00108          break;
00109       case kLong64_t:
00110          b.ReadFastArray(&itm->s_longlong, nElements);
00111          break;
00112       case kFloat_t:
00113          b.ReadFastArray(&itm->flt       , nElements);
00114          break;
00115       case kFloat16_t:
00116          b.ReadFastArrayFloat16(&itm->flt, nElements);
00117          break;
00118       case kDouble_t:
00119          b.ReadFastArray(&itm->dbl       , nElements);
00120          break;
00121       case kBOOL_t:
00122          b.ReadFastArray(&itm->boolean   , nElements);
00123          break;
00124       case kUChar_t:
00125          b.ReadFastArray(&itm->u_char    , nElements);
00126          break;
00127       case kUShort_t:
00128          b.ReadFastArray(&itm->u_short   , nElements);
00129          break;
00130       case kUInt_t:
00131          b.ReadFastArray(&itm->u_int     , nElements);
00132          break;
00133       case kULong_t:
00134          b.ReadFastArray(&itm->u_long    , nElements);
00135          break;
00136       case kULong64_t:
00137          b.ReadFastArray(&itm->u_longlong, nElements);
00138          break;
00139       case kDouble32_t:
00140          b.ReadFastArrayDouble32(&itm->dbl, nElements);
00141          break;
00142       case kchar:
00143       case kNoType_t:
00144       case kOther_t:
00145          Error("TGenCollectionStreamer", "fType %d is not supported yet!\n", fVal->fKind);
00146    }
00147    if (feed)  {      // need to feed in data...
00148       fEnv->fStart = fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00149       if (memory)  {
00150          ::operator delete(memory);
00151       }
00152    }
00153 }
00154 
00155 void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b)
00156 {
00157    // Object input streamer.
00158    Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3;
00159    size_t len = fValDiff * nElements;
00160    StreamHelper* itm = 0;
00161    char   buffer[8096];
00162    void*  memory = 0;
00163    
00164    TClass* onFileValClass = (fOnFileClass ? fOnFileClass->GetCollectionProxy()->GetValueClass() : 0);
00165 
00166    fEnv->fSize = nElements;
00167    switch (fSTL_type)  {
00168          // Simple case: contiguous memory. get address of first, then jump.
00169       case TClassEdit::kVector:
00170 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
00171          fResize(fEnv->fObject,fEnv->fSize);
00172          fEnv->fIdx = 0;
00173          
00174          {
00175             TVirtualVectorIterators iterators(fFunctionCreateIterators);
00176             iterators.CreateIterators(fEnv->fObject);
00177             itm = (StreamHelper*)iterators.fBegin;
00178          }
00179          fEnv->fStart = itm;
00180          switch (fVal->fCase) {
00181             case G__BIT_ISCLASS:
00182                DOLOOP(b.StreamObject(i, fVal->fType, onFileValClass ));
00183             case kBIT_ISSTRING:
00184                DOLOOP(i->read_std_string(b));
00185             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00186                DOLOOP(i->set(b.ReadObjectAny(fVal->fType)));
00187             case G__BIT_ISPOINTER | kBIT_ISSTRING:
00188                DOLOOP(i->read_std_string_pointer(b));
00189             case G__BIT_ISPOINTER | kBIT_ISTSTRING | G__BIT_ISCLASS:
00190                DOLOOP(i->read_tstring_pointer(vsn3, b));
00191          }
00192 #undef DOLOOP
00193          break;
00194 
00195          // No contiguous memory, but resize is possible
00196          // Hence accessing objects using At(i) should be not too much an overhead
00197       case TClassEdit::kList:
00198       case TClassEdit::kDeque:
00199 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
00200          fResize(fEnv->fObject,fEnv->fSize);
00201          fEnv->fIdx = 0;
00202          fEnv->fStart = 0;
00203          switch (fVal->fCase) {
00204             case G__BIT_ISCLASS:
00205                DOLOOP(b.StreamObject(i, fVal->fType, onFileValClass));
00206             case kBIT_ISSTRING:
00207                DOLOOP(i->read_std_string(b));
00208             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00209                DOLOOP(i->set(b.ReadObjectAny(fVal->fType)));
00210             case G__BIT_ISPOINTER | kBIT_ISSTRING:
00211                DOLOOP(i->read_std_string_pointer(b));
00212             case G__BIT_ISPOINTER | kBIT_ISTSTRING | G__BIT_ISCLASS:
00213                DOLOOP(i->read_tstring_pointer(vsn3, b));
00214          }
00215 #undef DOLOOP
00216          break;
00217 
00218          // Rather troublesome case: Objects can only be fed into the container
00219          // Once they are created. Need to take memory from stack or heap.
00220       case TClassEdit::kMultiSet:
00221       case TClassEdit::kSet:
00222 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
00223          fEnv->fStart = itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
00224          fConstruct(itm,nElements);
00225          switch (fVal->fCase) {
00226             case G__BIT_ISCLASS:
00227                DOLOOP(b.StreamObject(i, fVal->fType, onFileValClass));
00228                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00229                fDestruct(fEnv->fStart,fEnv->fSize);
00230                break;
00231             case kBIT_ISSTRING:
00232                DOLOOP(i->read_std_string(b))
00233                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00234                fDestruct(fEnv->fStart,fEnv->fSize);
00235                break;
00236             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00237                DOLOOP(i->set(b.ReadObjectAny(fVal->fType)));
00238                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00239                break;
00240             case G__BIT_ISPOINTER | kBIT_ISSTRING:
00241                DOLOOP(i->read_std_string_pointer(b))
00242                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00243                break;
00244             case G__BIT_ISPOINTER | kBIT_ISTSTRING | G__BIT_ISCLASS:
00245                DOLOOP(i->read_tstring_pointer(vsn3, b));
00246                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00247                break;
00248          }
00249 #undef DOLOOP
00250          break;
00251       default:
00252          break;
00253    }
00254    if (memory) {
00255       ::operator delete(memory);
00256    }
00257 }
00258 
00259 void TGenCollectionStreamer::ReadPairFromMap(int nElements, TBuffer &b)
00260 {
00261    // Input streamer to convert a map into another collection
00262 
00263    Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3;
00264    size_t len = fValDiff * nElements;
00265    StreamHelper* itm = 0;
00266    char   buffer[8096];
00267    void*  memory = 0;
00268 
00269    TStreamerInfo *pinfo = (TStreamerInfo*)fVal->fType->GetStreamerInfo();
00270    R__ASSERT(pinfo);
00271    R__ASSERT(fVal->fCase == G__BIT_ISCLASS);
00272 
00273    int nested = 0;
00274    std::vector<std::string> inside;
00275    TClassEdit::GetSplit(pinfo->GetName(), inside, nested);
00276    Value first(inside[1]);
00277    Value second(inside[2]);
00278    fValOffset = ((TStreamerElement*)pinfo->GetElements()->At(1))->GetOffset();
00279 
00280    fEnv->fSize = nElements;
00281    switch (fSTL_type)  {
00282          // Simple case: contiguous memory. get address of first, then jump.
00283       case TClassEdit::kVector:
00284 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
00285          fResize(fEnv->fObject,fEnv->fSize);
00286          fEnv->fIdx = 0;
00287          
00288          {
00289             TVirtualVectorIterators iterators(fFunctionCreateIterators);
00290             iterators.CreateIterators(fEnv->fObject);
00291             itm = (StreamHelper*)iterators.fBegin;
00292          }
00293          fEnv->fStart = itm;
00294          switch (fVal->fCase) {
00295             case G__BIT_ISCLASS:
00296                DOLOOP(
00297                   ReadMapHelper(i, &first, vsn3, b);
00298                   ReadMapHelper((StreamHelper*)(((char*)i) + fValOffset), &second, vsn3, b)
00299                );
00300          }
00301 #undef DOLOOP
00302          break;
00303 
00304          // No contiguous memory, but resize is possible
00305          // Hence accessing objects using At(i) should be not too much an overhead
00306       case TClassEdit::kList:
00307       case TClassEdit::kDeque:
00308 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
00309          fResize(fEnv->fObject,fEnv->fSize);
00310          fEnv->fIdx = 0;
00311          {
00312             TVirtualVectorIterators iterators(fFunctionCreateIterators);
00313             iterators.CreateIterators(fEnv->fObject);
00314             fEnv->fStart = iterators.fBegin;
00315          }
00316          switch (fVal->fCase) {
00317             case G__BIT_ISCLASS:
00318                DOLOOP(
00319                   char **where = (char**)(void*) & i;
00320                   pinfo->ReadBuffer(b, where, -1);
00321                );
00322          }
00323 #undef DOLOOP
00324          break;
00325 
00326          // Rather troublesome case: Objects can only be fed into the container
00327          // Once they are created. Need to take memory from stack or heap.
00328       case TClassEdit::kMultiSet:
00329       case TClassEdit::kSet:
00330 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
00331          fEnv->fStart = itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
00332          fConstruct(itm,nElements);
00333          switch (fVal->fCase) {
00334             case G__BIT_ISCLASS:
00335                DOLOOP(
00336                   char **where = (char**)(void*) & i;
00337                   pinfo->ReadBuffer(b, where, -1);
00338                );
00339                fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00340                fDestruct(fEnv->fStart,fEnv->fSize);
00341                break;
00342          }
00343 #undef DOLOOP
00344          break;
00345       default:
00346          break;
00347    }
00348    if (memory) {
00349       ::operator delete(memory);
00350    }
00351 }
00352 
00353 
00354 void TGenCollectionStreamer::ReadMapHelper(StreamHelper *i, Value *v, Bool_t vsn3,  TBuffer &b)
00355 {
00356    // helper class to read std::map
00357    
00358    float f;
00359 
00360    switch (v->fCase) {
00361       case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00362       case G__BIT_ISENUM:
00363          switch (int(v->fKind))   {
00364             case kBool_t:
00365                b >> i->boolean;
00366                break;
00367             case kChar_t:
00368                b >> i->s_char;
00369                break;
00370             case kShort_t:
00371                b >> i->s_short;
00372                break;
00373             case kInt_t:
00374                b >> i->s_int;
00375                break;
00376             case kLong_t:
00377                b >> i->s_long;
00378                break;
00379             case kLong64_t:
00380                b >> i->s_longlong;
00381                break;
00382             case kFloat_t:
00383                b >> i->flt;
00384                break;
00385             case kFloat16_t:
00386                b >> f;
00387                i->flt = float(f);
00388                break;
00389             case kDouble_t:
00390                b >> i->dbl;
00391                break;
00392             case kBOOL_t:
00393                b >> i->boolean;
00394                break;
00395             case kUChar_t:
00396                b >> i->u_char;
00397                break;
00398             case kUShort_t:
00399                b >> i->u_short;
00400                break;
00401             case kUInt_t:
00402                b >> i->u_int;
00403                break;
00404             case kULong_t:
00405                b >> i->u_long;
00406                break;
00407             case kULong64_t:
00408                b >> i->u_longlong;
00409                break;
00410             case kDouble32_t:
00411                b >> f;
00412                i->dbl = double(f);
00413                break;
00414             case kchar:
00415             case kNoType_t:
00416             case kOther_t:
00417                Error("TGenCollectionStreamer", "fType %d is not supported yet!\n", v->fKind);
00418          }
00419          break;
00420       case G__BIT_ISCLASS:
00421          b.StreamObject(i, v->fType);
00422          break;
00423       case kBIT_ISSTRING:
00424          i->read_std_string(b);
00425          break;
00426       case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00427          i->set(b.ReadObjectAny(v->fType));
00428          break;
00429       case G__BIT_ISPOINTER | kBIT_ISSTRING:
00430          i->read_std_string_pointer(b);
00431          break;
00432       case G__BIT_ISPOINTER | kBIT_ISTSTRING | G__BIT_ISCLASS:
00433          i->read_tstring_pointer(vsn3, b);
00434          break;
00435    }
00436 }
00437 
00438 void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b)
00439 {
00440    // Map input streamer.
00441    Bool_t vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion() <= 3;
00442    size_t len = fValDiff * nElements;
00443    Value  *v;
00444    char buffer[8096], *addr, *temp;
00445    void* memory = 0;
00446    StreamHelper* i;
00447    float f;
00448    fEnv->fSize  = nElements;
00449    fEnv->fStart = (len < sizeof(buffer) ? buffer : memory =::operator new(len));
00450    addr = temp = (char*)fEnv->fStart;
00451    fConstruct(addr,nElements);
00452    for (int loop, idx = 0; idx < nElements; ++idx)  {
00453       addr = temp + fValDiff * idx;
00454       v = fKey;
00455       for (loop = 0; loop < 2; loop++)  {
00456          i = (StreamHelper*)addr;
00457          switch (v->fCase) {
00458             case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00459             case G__BIT_ISENUM:
00460                switch (int(v->fKind))   {
00461                   case kBool_t:
00462                      b >> i->boolean;
00463                      break;
00464                   case kChar_t:
00465                      b >> i->s_char;
00466                      break;
00467                   case kShort_t:
00468                      b >> i->s_short;
00469                      break;
00470                   case kInt_t:
00471                      b >> i->s_int;
00472                      break;
00473                   case kLong_t:
00474                      b >> i->s_long;
00475                      break;
00476                   case kLong64_t:
00477                      b >> i->s_longlong;
00478                      break;
00479                   case kFloat_t:
00480                      b >> i->flt;
00481                      break;
00482                   case kFloat16_t:
00483                      b >> f;
00484                      i->flt = float(f);
00485                      break;
00486                   case kDouble_t:
00487                      b >> i->dbl;
00488                      break;
00489                   case kBOOL_t:
00490                      b >> i->boolean;
00491                      break;
00492                   case kUChar_t:
00493                      b >> i->u_char;
00494                      break;
00495                   case kUShort_t:
00496                      b >> i->u_short;
00497                      break;
00498                   case kUInt_t:
00499                      b >> i->u_int;
00500                      break;
00501                   case kULong_t:
00502                      b >> i->u_long;
00503                      break;
00504                   case kULong64_t:
00505                      b >> i->u_longlong;
00506                      break;
00507                   case kDouble32_t:
00508                      b >> f;
00509                      i->dbl = double(f);
00510                      break;
00511                   case kchar:
00512                   case kNoType_t:
00513                   case kOther_t:
00514                      Error("TGenCollectionStreamer", "fType %d is not supported yet!\n", v->fKind);
00515                }
00516                break;
00517             case G__BIT_ISCLASS:
00518                b.StreamObject(i, v->fType);
00519                break;
00520             case kBIT_ISSTRING:
00521                i->read_std_string(b);
00522                break;
00523             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00524                i->set(b.ReadObjectAny(v->fType));
00525                break;
00526             case G__BIT_ISPOINTER | kBIT_ISSTRING:
00527                i->read_std_string_pointer(b);
00528                break;
00529             case G__BIT_ISPOINTER | kBIT_ISTSTRING | G__BIT_ISCLASS:
00530                i->read_tstring_pointer(vsn3, b);
00531                break;
00532          }
00533          v = fVal;
00534          addr += fValOffset;
00535       }
00536    }
00537    fFeed(fEnv->fStart,fEnv->fObject,fEnv->fSize);
00538    fDestruct(fEnv->fStart,fEnv->fSize);
00539    if (memory) {
00540       ::operator delete(memory);
00541    }
00542 }
00543 
00544 void TGenCollectionStreamer::WritePrimitives(int nElements, TBuffer &b)
00545 {
00546    // Primitive output streamer.
00547    size_t len = fValDiff * nElements;
00548    char   buffer[8192];
00549    void*  memory  = 0;
00550    StreamHelper* itm = 0;
00551    switch (fSTL_type)  {
00552       case TClassEdit::kVector:
00553          if (fVal->fKind != EDataType(kBOOL_t))  {
00554             itm = (StreamHelper*)(fEnv->fStart = fFirst.invoke(fEnv));
00555             break;
00556          }
00557       default:
00558          fEnv->fStart = itm = (StreamHelper*)(len < sizeof(buffer) ? buffer : memory =::operator new(len));
00559          fCollect.invoke(fEnv);
00560          break;
00561    }
00562    switch (int(fVal->fKind))   {
00563       case kBool_t:
00564          b.WriteFastArray(&itm->boolean    , nElements);
00565          break;
00566       case kChar_t:
00567          b.WriteFastArray(&itm->s_char    , nElements);
00568          break;
00569       case kShort_t:
00570          b.WriteFastArray(&itm->s_short   , nElements);
00571          break;
00572       case kInt_t:
00573          b.WriteFastArray(&itm->s_int     , nElements);
00574          break;
00575       case kLong_t:
00576          b.WriteFastArray(&itm->s_long    , nElements);
00577          break;
00578       case kLong64_t:
00579          b.WriteFastArray(&itm->s_longlong, nElements);
00580          break;
00581       case kFloat_t:
00582          b.WriteFastArray(&itm->flt       , nElements);
00583          break;
00584       case kFloat16_t:
00585          b.WriteFastArrayFloat16(&itm->flt, nElements);
00586          break;
00587       case kDouble_t:
00588          b.WriteFastArray(&itm->dbl       , nElements);
00589          break;
00590       case kBOOL_t:
00591          b.WriteFastArray(&itm->boolean   , nElements);
00592          break;
00593       case kUChar_t:
00594          b.WriteFastArray(&itm->u_char    , nElements);
00595          break;
00596       case kUShort_t:
00597          b.WriteFastArray(&itm->u_short   , nElements);
00598          break;
00599       case kUInt_t:
00600          b.WriteFastArray(&itm->u_int     , nElements);
00601          break;
00602       case kULong_t:
00603          b.WriteFastArray(&itm->u_long    , nElements);
00604          break;
00605       case kULong64_t:
00606          b.WriteFastArray(&itm->u_longlong, nElements);
00607          break;
00608       case kDouble32_t:
00609          b.WriteFastArrayDouble32(&itm->dbl, nElements);
00610          break;
00611       case kchar:
00612       case kNoType_t:
00613       case kOther_t:
00614          Error("TGenCollectionStreamer", "fType %d is not supported yet!\n", fVal->fKind);
00615    }
00616    if (memory)  {
00617       ::operator delete(memory);
00618    }
00619 }
00620 
00621 void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b)
00622 {
00623    // Object output streamer.
00624    StreamHelper* itm = 0;
00625    switch (fSTL_type)  {
00626          // Simple case: contiguous memory. get address of first, then jump.
00627       case TClassEdit::kVector:
00628 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
00629          itm = (StreamHelper*)fFirst.invoke(fEnv);
00630          switch (fVal->fCase) {
00631             case G__BIT_ISCLASS:
00632                DOLOOP(b.StreamObject(i, fVal->fType));
00633                break;
00634             case kBIT_ISSTRING:
00635                DOLOOP(TString(i->c_str()).Streamer(b));
00636                break;
00637             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00638                DOLOOP(b.WriteObjectAny(i->ptr(), fVal->fType));
00639                break;
00640             case kBIT_ISSTRING | G__BIT_ISPOINTER:
00641                DOLOOP(i->write_std_string_pointer(b));
00642                break;
00643             case kBIT_ISTSTRING | G__BIT_ISCLASS | G__BIT_ISPOINTER:
00644                DOLOOP(i->write_tstring_pointer(b));
00645                break;
00646          }
00647 #undef DOLOOP
00648          break;
00649 
00650          // No contiguous memory, but resize is possible
00651          // Hence accessing objects using At(i) should be not too much an overhead
00652       case TClassEdit::kList:
00653       case TClassEdit::kDeque:
00654       case TClassEdit::kMultiSet:
00655       case TClassEdit::kSet:
00656 #define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
00657          switch (fVal->fCase) {
00658             case G__BIT_ISCLASS:
00659                DOLOOP(b.StreamObject(i, fVal->fType));
00660             case kBIT_ISSTRING:
00661                DOLOOP(TString(i->c_str()).Streamer(b));
00662             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00663                DOLOOP(b.WriteObjectAny(i->ptr(), fVal->fType));
00664             case kBIT_ISSTRING | G__BIT_ISPOINTER:
00665                DOLOOP(i->write_std_string_pointer(b));
00666             case kBIT_ISTSTRING | G__BIT_ISCLASS | G__BIT_ISPOINTER:
00667                DOLOOP(i->write_tstring_pointer(b));
00668          }
00669 #undef DOLOOP
00670          break;
00671       default:
00672          break;
00673    }
00674 }
00675 
00676 void TGenCollectionStreamer::WriteMap(int nElements, TBuffer &b)
00677 {
00678    // Map output streamer
00679    StreamHelper* i;
00680    Value  *v;
00681 
00682    for (int loop, idx = 0; idx < nElements; ++idx)  {
00683       char* addr = (char*)TGenCollectionProxy::At(idx);
00684       v = fKey;
00685       for (loop = 0; loop < 2; ++loop)  {
00686          i = (StreamHelper*)addr;
00687          switch (v->fCase) {
00688             case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00689             case G__BIT_ISENUM:
00690                switch (int(v->fKind))   {
00691                   case kBool_t:
00692                      b << i->boolean;
00693                      break;
00694                   case kChar_t:
00695                      b << i->s_char;
00696                      break;
00697                   case kShort_t:
00698                      b << i->s_short;
00699                      break;
00700                   case kInt_t:
00701                      b << i->s_int;
00702                      break;
00703                   case kLong_t:
00704                      b << i->s_long;
00705                      break;
00706                   case kLong64_t:
00707                      b << i->s_longlong;
00708                      break;
00709                   case kFloat_t:
00710                      b << i->flt;
00711                      break;
00712                   case kFloat16_t:
00713                      b << float(i->flt);
00714                      break;
00715                   case kDouble_t:
00716                      b << i->dbl;
00717                      break;
00718                   case kBOOL_t:
00719                      b << i->boolean;
00720                      break;
00721                   case kUChar_t:
00722                      b << i->u_char;
00723                      break;
00724                   case kUShort_t:
00725                      b << i->u_short;
00726                      break;
00727                   case kUInt_t:
00728                      b << i->u_int;
00729                      break;
00730                   case kULong_t:
00731                      b << i->u_long;
00732                      break;
00733                   case kULong64_t:
00734                      b << i->u_longlong;
00735                      break;
00736                   case kDouble32_t:
00737                      b << float(i->dbl);
00738                      break;
00739                   case kchar:
00740                   case kNoType_t:
00741                   case kOther_t:
00742                      Error("TGenCollectionStreamer", "fType %d is not supported yet!\n", v->fKind);
00743                }
00744                break;
00745             case G__BIT_ISCLASS:
00746                b.StreamObject(i, v->fType);
00747                break;
00748             case kBIT_ISSTRING:
00749                TString(i->c_str()).Streamer(b);
00750                break;
00751             case G__BIT_ISPOINTER | G__BIT_ISCLASS:
00752                b.WriteObjectAny(i->ptr(), v->fType);
00753                break;
00754             case kBIT_ISSTRING | G__BIT_ISPOINTER:
00755                i->write_std_string_pointer(b);
00756                break;
00757             case kBIT_ISTSTRING | G__BIT_ISCLASS | G__BIT_ISPOINTER:
00758                i->write_tstring_pointer(b);
00759                break;
00760          }
00761          addr += fValOffset;
00762          v = fVal;
00763       }
00764    }
00765 }
00766 
00767 template <typename basictype>
00768 void TGenCollectionStreamer::ReadBufferVectorPrimitives(TBuffer &b, void *obj)
00769 {
00770    int nElements = 0;
00771    b >> nElements;
00772    fResize(obj,nElements);
00773    
00774    TVirtualVectorIterators iterators(fFunctionCreateIterators);
00775    iterators.CreateIterators(obj);
00776    b.ReadFastArray((basictype*)iterators.fBegin, nElements);
00777 }
00778 
00779 void TGenCollectionStreamer::ReadBufferVectorPrimitivesFloat16(TBuffer &b, void *obj)
00780 {
00781    int nElements = 0;
00782    b >> nElements;
00783    fResize(obj,nElements);
00784    
00785    TVirtualVectorIterators iterators(fFunctionCreateIterators);
00786    iterators.CreateIterators(obj);
00787    b.ReadFastArrayFloat16((Float16_t*)iterators.fBegin, nElements);
00788 }
00789 
00790 void TGenCollectionStreamer::ReadBufferVectorPrimitivesDouble32(TBuffer &b, void *obj)
00791 {
00792    int nElements = 0;
00793    b >> nElements;
00794    fResize(obj,nElements);
00795    
00796    TVirtualVectorIterators iterators(fFunctionCreateIterators);
00797    iterators.CreateIterators(obj);
00798    b.ReadFastArrayDouble32((Double32_t*)iterators.fBegin, nElements);
00799 }
00800 
00801 
00802 
00803 void TGenCollectionStreamer::ReadBuffer(TBuffer &b, void *obj, const TClass *onFileClass)
00804 {
00805    // Call the specialized function.  The first time this call ReadBufferDefault which
00806    // actually set to fReadBufferFunc to the 'right' specialized version.
00807    
00808    SetOnFileClass((TClass*)onFileClass);
00809    (this->*fReadBufferFunc)(b,obj);
00810 }
00811 
00812 void TGenCollectionStreamer::ReadBuffer(TBuffer &b, void *obj)
00813 {
00814    // Call the specialized function.  The first time this call ReadBufferDefault which
00815    // actually set to fReadBufferFunc to the 'right' specialized version.
00816    
00817    (this->*fReadBufferFunc)(b,obj);
00818 }
00819 
00820 void TGenCollectionStreamer::ReadBufferDefault(TBuffer &b, void *obj)
00821 {
00822  
00823    fReadBufferFunc = &TGenCollectionStreamer::ReadBufferGeneric;
00824    // We will need this later, so let's make sure it is initialized.
00825    if (!GetFunctionCreateIterators()) {
00826       Fatal("TGenCollectionStreamer::ReadBufferDefault","No CreateIterators function for %s",fName.c_str());
00827    }
00828    if (fSTL_type == TClassEdit::kVector && ( fVal->fCase == G__BIT_ISFUNDAMENTAL || fVal->fCase == G__BIT_ISENUM ) )
00829    {
00830       // Only handle primitives this way
00831       switch (int(fVal->fKind))   {
00832          case kBool_t:
00833             // Nothing use generic for now
00834             break;
00835          case kChar_t:
00836             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Char_t>;
00837             break;
00838          case kShort_t:
00839             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Short_t>;
00840             break;
00841          case kInt_t:
00842             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Int_t>;
00843             break;
00844          case kLong_t:
00845             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Long_t>;
00846             break;
00847          case kLong64_t:
00848             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Long64_t>;
00849             break;
00850          case kFloat_t:
00851             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Float_t>;
00852             break;
00853          case kFloat16_t:
00854             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitivesFloat16;
00855             break;
00856          case kDouble_t:
00857             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<Double_t>;
00858             break;
00859 //         case kBOOL_t:
00860 //            fReadBufferFunc = &ReadBufferVectorPrimitives<>;
00861 //            break;
00862          case kUChar_t:
00863             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<UChar_t>;
00864             break;
00865          case kUShort_t:
00866             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<UShort_t>;
00867             break;
00868          case kUInt_t:
00869             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<UInt_t>;
00870             break;
00871          case kULong_t:
00872             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<ULong_t>;
00873             break;
00874          case kULong64_t:
00875             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitives<ULong64_t>;
00876             break;
00877          case kDouble32_t:
00878             fReadBufferFunc = &TGenCollectionStreamer::ReadBufferVectorPrimitivesDouble32;
00879             break;
00880          case kchar:
00881          case kNoType_t:
00882          case kOther_t:
00883             // Nothing use the generic for now
00884             break;
00885       }
00886    }
00887    (this->*fReadBufferFunc)(b,obj);
00888 }
00889 
00890 void TGenCollectionStreamer::ReadBufferGeneric(TBuffer &b, void *obj)
00891 {
00892    TVirtualCollectionProxy::TPushPop env(this, obj);
00893 
00894    int nElements = 0;
00895    b >> nElements;
00896 
00897    if (nElements == 0) {
00898       if (obj) {
00899          TGenCollectionProxy::Clear("force");
00900       }
00901    } else if (nElements > 0)  {
00902       switch (fSTL_type)  {
00903          case TClassEdit::kBitSet:
00904             if (obj) {
00905                if (fPointers)   {
00906                   TGenCollectionProxy::Clear("force");
00907                }  else {
00908                   fClear.invoke(fEnv);
00909                }
00910             }
00911             ReadPrimitives(nElements, b);
00912             return;
00913          case TClassEdit::kVector:
00914             if (obj) {
00915                if (fPointers)   {
00916                   TGenCollectionProxy::Clear("force");
00917                } // a resize will be called in ReadPrimitives/ReadObjects.
00918                else if (fVal->fKind == EDataType(kBOOL_t)) {
00919                   fClear.invoke(fEnv);                  
00920                }
00921             }
00922             switch (fVal->fCase) {
00923                case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00924                case G__BIT_ISENUM:
00925                   ReadPrimitives(nElements, b);
00926                   return;
00927                default:
00928                   ReadObjects(nElements, b);
00929                   return;
00930             }
00931             break;
00932          case TClassEdit::kList:
00933          case TClassEdit::kDeque:
00934          case TClassEdit::kMultiSet:
00935          case TClassEdit::kSet:
00936             if (obj) {
00937                if (fPointers)   {
00938                   TGenCollectionProxy::Clear("force");
00939                }  else {
00940                   fClear.invoke(fEnv);
00941                }
00942             }
00943             switch (fVal->fCase) {
00944                case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00945                case G__BIT_ISENUM:
00946                   ReadPrimitives(nElements, b);
00947                   return;
00948                default:
00949                   ReadObjects(nElements, b);
00950                   return;
00951             }
00952             break;
00953          case TClassEdit::kMap:
00954          case TClassEdit::kMultiMap:
00955             if (obj) {
00956                if (fPointers)   {
00957                   TGenCollectionProxy::Clear("force");
00958                }  else {
00959                   fClear.invoke(fEnv);
00960                }
00961             }
00962             ReadMap(nElements, b);
00963             break;
00964       }
00965    }
00966 }
00967 
00968 void TGenCollectionStreamer::Streamer(TBuffer &b)
00969 {
00970    // TClassStreamer IO overload.
00971    if (b.IsReading()) {    //Read mode
00972       int nElements = 0;
00973       b >> nElements;
00974       if (fEnv->fObject)   {
00975          TGenCollectionProxy::Clear("force");
00976       }
00977       if (nElements > 0)  {
00978          switch (fSTL_type)  {
00979             case TClassEdit::kBitSet:
00980                ReadPrimitives(nElements, b);
00981                return;
00982             case TClassEdit::kVector:
00983             case TClassEdit::kList:
00984             case TClassEdit::kDeque:
00985             case TClassEdit::kMultiSet:
00986             case TClassEdit::kSet:
00987                switch (fVal->fCase) {
00988                   case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
00989                   case G__BIT_ISENUM:
00990                      ReadPrimitives(nElements, b);
00991                      return;
00992                   default:
00993                      ReadObjects(nElements, b);
00994                      return;
00995                }
00996                break;
00997             case TClassEdit::kMap:
00998             case TClassEdit::kMultiMap:
00999                ReadMap(nElements, b);
01000                break;
01001          }
01002       }
01003    } else {    // Write case
01004       int nElements = fEnv->fObject ? *(size_t*)fSize.invoke(fEnv) : 0;
01005       b << nElements;
01006       if (nElements > 0)  {
01007          switch (fSTL_type)  {
01008             case TClassEdit::kBitSet:
01009                WritePrimitives(nElements, b);
01010                return;
01011             case TClassEdit::kVector:
01012             case TClassEdit::kList:
01013             case TClassEdit::kDeque:
01014             case TClassEdit::kMultiSet:
01015             case TClassEdit::kSet:
01016                switch (fVal->fCase) {
01017                   case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
01018                   case G__BIT_ISENUM:
01019                      WritePrimitives(nElements, b);
01020                      return;
01021                   default:
01022                      WriteObjects(nElements, b);
01023                      return;
01024                }
01025                break;
01026             case TClassEdit::kMap:
01027             case TClassEdit::kMultiMap:
01028                WriteMap(nElements, b);
01029                break;
01030          }
01031       }
01032    }
01033 }
01034 
01035 void TGenCollectionStreamer::StreamerAsMap(TBuffer &b)
01036 {
01037    // TClassStreamer IO overload.
01038    if (b.IsReading()) {    //Read mode
01039       int nElements = 0;
01040       b >> nElements;
01041       if (fEnv->fObject)   {
01042          TGenCollectionProxy::Clear("force");
01043       }
01044       if (nElements > 0)  {
01045          switch (fSTL_type)  {
01046             case TClassEdit::kMap:
01047             case TClassEdit::kMultiMap:
01048                ReadMap(nElements, b);
01049                break;
01050             case TClassEdit::kVector:
01051             case TClassEdit::kList:
01052             case TClassEdit::kDeque:
01053             case TClassEdit::kMultiSet:
01054             case TClassEdit::kSet: {
01055                   ReadPairFromMap(nElements, b);
01056                   break;
01057                }
01058             default:
01059                break;
01060          }
01061       }
01062    } else {    // Write case
01063       Streamer(b);
01064    }
01065 }

Generated on Tue Jul 5 14:30:18 2011 for ROOT_528-00b_version by  doxygen 1.5.1