CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TBufferBlobStreamingService.cc
Go to the documentation of this file.
4 //
5 #include <algorithm>
6 #include <typeinfo>
7 #include <string>
8 #include <cstring>
9 //
10 #include "TBufferFile.h"
11 
13 
14 typedef void (TBuffer::*WriteArrayFn_t)(const void *obj, Int_t n);
15 typedef void (TBuffer::*ReadArrayFn_t)(void *obj, Int_t n);
16 
17 #define PRIMITIVE(x) { \
18  typeid(x), \
19  reinterpret_cast<WriteArrayFn_t>( \
20  (void (TBuffer::*)(const x*, Int_t))&TBuffer::WriteFastArray), \
21  reinterpret_cast<ReadArrayFn_t>( \
22  (void (TBuffer::*)(x*, Int_t))&TBuffer::ReadFastArray) \
23 }
24 
25 struct Primitive {
26  const std::type_info &type;
29 
30  inline bool operator == (const std::type_info &other) const
31  { return type == other; }
32 } static const primitives[] = {
33  PRIMITIVE(Bool_t),
34  PRIMITIVE(Char_t),
35  PRIMITIVE(UChar_t),
36  PRIMITIVE(Short_t),
37  PRIMITIVE(UShort_t),
38  PRIMITIVE(Int_t),
39  PRIMITIVE(UInt_t),
40  PRIMITIVE(Long_t),
41  PRIMITIVE(ULong_t),
42  PRIMITIVE(Long64_t),
43  PRIMITIVE(ULong64_t),
44  PRIMITIVE(Float_t),
45  PRIMITIVE(Double_t)
46 };
47 
48 static const std::size_t nPrimitives =
49  (sizeof primitives / sizeof primitives[0]);
50 
51 #undef PRIMTIVE
52 
54  : m_arraySize(0), m_class(0), m_primitive(0)
55 {
56  edm::TypeWithDict type = type_;
57  while(true) {
58  type = type.finalType();
59 
60  if (!type.isArray())
61  break;
62 
63  if (!m_arraySize)
64  m_arraySize = 1;
65  m_arraySize *= type.arrayLength();
66  type = type.toType();
67  }
68 
69  if (type.isClass()) {
70  const std::type_info &typeInfo = type.typeInfo();
71  m_class = TClass::GetClass(typeInfo);
72  if (!m_class)
73  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
74  "No ROOT class registered for " + type.name());
75  } else if (type.isFundamental()) {
76  if (!m_arraySize)
77  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
78  "Only arrays of primitive types supported. "
79  "Please to not use a Blob for this member.");
80 
82  type.typeInfo()) - primitives;
83  if (m_primitive >= nPrimitives)
84  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
85  "Cannot handle primitive type " + type.name());
86  } else
87  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
88  "Cannot handle C++ type " + type.name());
89 }
90 
91 
93 }
94 
96 }
97 
98 #include <boost/bind.hpp>
99 namespace {
100  inline char * reallocInBlob( boost::shared_ptr<coral::Blob> theBlob, char* p, size_t newsize, size_t oldsize) {
101  // various checks missing....
102  theBlob->resize(newsize);
103  return (char*)theBlob->startingAddress();
104 
105  }
106 }
107 
108 boost::shared_ptr<coral::Blob> cond::TBufferBlobStreamingService::write( const void* addr,
109  edm::TypeWithDict const & classDictionary,
110  bool ){
111  TBufferBlobTypeInfo theType( classDictionary );
112  if (theType.m_class && theType.m_class->GetActualClass(addr) != theType.m_class)
113  throw cond::Exception("TBufferBlobWriter::write object to stream is "
114  "not of actual class.");
115 
116  boost::shared_ptr<coral::Blob> theBlob( new coral::Blob );
117  //theBlob->resize(1024);
118 
119  // with new root...
120  // TBufferFile buffer(TBufferFile::kWrite, theBlob->size(), theBlob->startingAddress(), kFALSE, boost::bind(reallocInBlob, theBlob,_1,_2,_3));
121  TBufferFile buffer(TBufferFile::kWrite);
122  buffer.InitMap();
123 
124  if (theType.m_arraySize && !theType.m_class)
125  (buffer.*primitives[theType.m_primitive].writeArrayFn)(addr, theType.m_arraySize);
126  else if (theType.m_arraySize)
127  buffer.WriteFastArray(const_cast<void*>(addr), theType.m_class, theType.m_arraySize);
128  else
129  buffer.StreamObject(const_cast<void*>(addr), theType.m_class);
130 
131  Int_t size = buffer.Length();
132 
133  theBlob->resize(size);
134  void *startingAddress = theBlob->startingAddress();
135  std::memcpy(startingAddress, buffer.Buffer(), size);
136 
137  return theBlob;
138 }
139 
140 void cond::TBufferBlobStreamingService::read( const coral::Blob& blobData,
141  void* addr,
142  edm::TypeWithDict const & classDictionary ){
143  TBufferBlobTypeInfo theType( classDictionary );
144  const void *startingAddress = blobData.startingAddress();
145  size_t size = blobData.size();
146  if (!size)
147  return;
148 
149  TBufferFile buffer(TBufferFile::kRead, size,
150  const_cast<void*>(startingAddress), kFALSE);
151 
152  buffer.InitMap();
153 
154  if (theType.m_arraySize && !theType.m_class)
155  (buffer.*primitives[theType.m_primitive].readArrayFn)(addr, theType.m_arraySize);
156  else if (theType.m_arraySize)
157  buffer.ReadFastArray(addr, theType.m_class, theType.m_arraySize);
158  else
159  buffer.StreamObject(addr, theType.m_class);
160 }
161 
type
Definition: HCALResponse.h:21
TBufferBlobTypeInfo(const edm::TypeWithDict &type)
std::size_t m_arraySize
length of the plain C array (zero otherwise)
#define PRIMITIVE(x)
TypeWithDict finalType() const
void read(const coral::Blob &blobData, void *addressOfContainer, edm::TypeWithDict const &classDictionary)
Reads an object from a Blob and fills-in the container.
TClass * m_class
The class as seen by the ROOT streaming services.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
TypeWithDict toType() const
unsigned int m_primitive
the primitive C++ type if m_class is unset
boost::shared_ptr< coral::Blob > write(const void *addressOfInputData, edm::TypeWithDict const &classDictionary, bool useCompression=false)
const std::type_info & type
bool isArray() const
std::string name() const
bool isClass() const
bool isFundamental() const
std::type_info const & typeInfo() const
double const * startingAddress(ArrayAdaptor const &iV)
void(TBuffer::* ReadArrayFn_t)(void *obj, Int_t n)
static const std::size_t nPrimitives
ReadArrayFn_t readArrayFn
size_t arrayLength() const
WriteArrayFn_t writeArrayFn
void(TBuffer::* WriteArrayFn_t)(const void *obj, Int_t n)
tuple size
Write out results.
struct Primitive primitives[]
bool operator==(const std::type_info &other) const