Revision 9a9e5b4cf3f43c391212ffc2c292ca1ffdba8767 authored by Unknown Author on 08 May 2006, 14:01:31 UTC, committed by Unknown Author on 08 May 2006, 14:01:31 UTC
git-svn-id: http://root.cern.ch/svn/root/tags/v5-11-02@14953 27541ba8-7e3a-0410-8455-c3a389f83636
1 parent 28e762f
TCollectionProxy.cxx
// @(#)root/cont:$Name: $:$Id: TCollectionProxy.cxx,v 1.6 2005/11/16 20:07:50 pcanal Exp $
// 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. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TGenCollectionProxy
//
// 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 fucntions.
//
// 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 "TError.h"
#include "TClassEdit.h"
#include "TCollectionProxy.h"
#include "TGenCollectionProxy.h"
#include "TGenCollectionStreamer.h"
#include "TEmulatedMapProxy.h"
#include "TEmulatedCollectionProxy.h"
// Do not clutter global namespace with shit....
namespace {
static TClassEdit::ESTLType stl_type(const std::string& class_name) {
// return the STL type.
int nested = 0;
std::vector<std::string> inside;
int num = TClassEdit::GetSplit(class_name.c_str(),inside,nested);
if ( num > 1 ) {
return (TClassEdit::ESTLType)TClassEdit::STLKind(inside[0].c_str());
}
return TClassEdit::kNotSTL;
}
static TEmulatedCollectionProxy* GenEmulation(const char* class_name) {
// Generate an emulated collection proxy.
if ( class_name ) {
std::string cl = class_name;
if ( cl.find("stdext::hash_") != std::string::npos )
cl.replace(3,10,"::");
if ( cl.find("__gnu_cxx::hash_") != std::string::npos )
cl.replace(0,16,"std::");
switch ( stl_type(cl) ) {
case TClassEdit::kNotSTL:
return 0;
case TClassEdit::kMap:
case TClassEdit::kMultiMap:
return new TEmulatedMapProxy(class_name);
default:
return new TEmulatedCollectionProxy(class_name);
}
}
return 0;
}
}
TVirtualCollectionProxy*
TCollectionProxy::GenEmulatedProxy(const char* class_name)
{
// Generate emulated collection proxy for a given class.
return GenEmulation(class_name);
}
TClassStreamer*
TCollectionProxy::GenEmulatedClassStreamer(const char* class_name)
{
// Generate emulated class streamer for a given collection class.
TCollectionClassStreamer* s = new TCollectionClassStreamer();
s->AdoptStreamer(GenEmulation(class_name));
return s;
}
TMemberStreamer*
TCollectionProxy::GenEmulatedMemberStreamer(const char* class_name)
{
// Generate emulated member streamer for a given collection class.
TCollectionMemberStreamer* s = new TCollectionMemberStreamer();
s->AdoptStreamer(GenEmulation(class_name));
return s;
}
TCollectionProxy::Proxy_t*
TCollectionProxy::GenExplicitProxy( Info_t info,
size_t iter_size,
size_t value_diff,
int value_offset,
void* (*size_func)(void*),
void* (*resize_func)(void*),
void* (*clear_func)(void*),
void* (*first_func)(void*),
void* (*next_func)(void*),
void* (*construct_func)(void*),
void* (*destruct_func)(void*),
void* (*feed_func)(void*),
void* (*collect_func)(void*)
)
{
// Generate proxy from static functions.
TGenCollectionProxy* ptr = new TGenCollectionProxy(info, iter_size);
ptr->fValDiff = value_diff;
ptr->fValOffset = value_offset;
ptr->fSize.call = size_func;
ptr->fResize.call = resize_func;
ptr->fNext.call = next_func;
ptr->fFirst.call = first_func;
ptr->fClear.call = clear_func;
ptr->fConstruct.call = construct_func;
ptr->fDestruct.call = destruct_func;
ptr->fFeed.call = feed_func;
ptr->fCollect.call = collect_func;
ptr->CheckFunctions();
return ptr;
}
TGenCollectionStreamer*
TCollectionProxy::GenExplicitStreamer( Info_t info,
size_t iter_size,
size_t value_diff,
int value_offset,
void* (*size_func)(void*),
void* (*resize_func)(void*),
void* (*clear_func)(void*),
void* (*first_func)(void*),
void* (*next_func)(void*),
void* (*construct_func)(void*),
void* (*destruct_func)(void*),
void* (*feed_func)(void*),
void* (*collect_func)(void*)
)
{
// Generate streamer from static functions.
TGenCollectionStreamer* ptr = new TGenCollectionStreamer(info, iter_size);
ptr->fValDiff = value_diff;
ptr->fValOffset = value_offset;
ptr->fSize.call = size_func;
ptr->fResize.call = resize_func;
ptr->fNext.call = next_func;
ptr->fFirst.call = first_func;
ptr->fClear.call = clear_func;
ptr->fConstruct.call = construct_func;
ptr->fDestruct.call = destruct_func;
ptr->fFeed.call = feed_func;
ptr->fCollect.call = collect_func;
ptr->CheckFunctions();
return ptr;
}
TClassStreamer*
TCollectionProxy::GenExplicitClassStreamer( Info_t info,
size_t iter_size,
size_t value_diff,
int value_offset,
void* (*size_func)(void*),
void* (*resize_func)(void*),
void* (*clear_func)(void*),
void* (*first_func)(void*),
void* (*next_func)(void*),
void* (*construct_func)(void*),
void* (*destruct_func)(void*),
void* (*feed_func)(void*),
void* (*collect_func)(void*)
)
{
// Generate class streamer from static functions.
TCollectionClassStreamer* s = new TCollectionClassStreamer();
s->AdoptStreamer(GenExplicitStreamer(info,
iter_size,
value_diff,
value_offset,
size_func,
resize_func,
clear_func,
first_func,
next_func,
construct_func,
destruct_func,
feed_func,
collect_func));
return s;
}
TMemberStreamer*
TCollectionProxy::GenExplicitMemberStreamer(Info_t info,
size_t iter_size,
size_t value_diff,
int value_offset,
void* (*size_func)(void*),
void* (*resize_func)(void*),
void* (*clear_func)(void*),
void* (*first_func)(void*),
void* (*next_func)(void*),
void* (*construct_func)(void*),
void* (*destruct_func)(void*),
void* (*feed_func)(void*),
void* (*collect_func)(void*)
)
{
// Generate member streamer from static functions.
TCollectionMemberStreamer* s = new TCollectionMemberStreamer();
s->AdoptStreamer(GenExplicitStreamer(info,
iter_size,
value_diff,
value_offset,
size_func,
resize_func,
clear_func,
first_func,
next_func,
construct_func,
destruct_func,
feed_func,
collect_func));
return s;
}
void TCollectionStreamer::InvalidProxyError() {
// Issue Error about invalid proxy.
Fatal("TCollectionStreamer>","No proxy available. Data streaming impossible.");
}
TCollectionStreamer::TCollectionStreamer() : fStreamer(0)
{
// Initializing constructor.
}
TCollectionStreamer::TCollectionStreamer(const TCollectionStreamer& c)
{
// Copy constructor.
if ( c.fStreamer ) {
fStreamer = dynamic_cast<TGenCollectionProxy*>(c.fStreamer->Generate());
R__ASSERT(fStreamer != 0);
return;
}
InvalidProxyError();
}
TCollectionStreamer::~TCollectionStreamer()
{
// Standard destructor.
if ( fStreamer ) {
delete fStreamer;
}
}
void TCollectionStreamer::AdoptStreamer(TGenCollectionProxy* streamer)
{
// Attach worker proxy.
if ( fStreamer ) {
delete fStreamer;
}
fStreamer = streamer;
}
void TCollectionStreamer::Streamer(TBuffer &buff, void *pObj, int /* siz */ )
{
// Streamer for I/O handling.
if ( fStreamer ) {
TVirtualCollectionProxy::TPushPop env(fStreamer, pObj);
fStreamer->Streamer(buff);
return;
}
InvalidProxyError();
}
Computing file changes ...