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 #include "Reflex/Reflex.h"
12 #include "Cintex/Cintex.h"
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  static bool cintexInitialized = false;
57  if (!cintexInitialized) {
58  cintexInitialized = true;
59  ROOT::Cintex::Cintex::Enable();
60  }
61 
62  Reflex::Type type = type_;
63  while(true) {
64  type = type.FinalType();
65 
66  if (!type.IsArray())
67  break;
68 
69  if (!m_arraySize)
70  m_arraySize = 1;
71  m_arraySize *= type.ArrayLength();
72  type = type.ToType();
73  }
74 
75  if (type.IsClass()) {
76  const std::type_info &typeInfo = type.TypeInfo();
77  m_class = TClass::GetClass(typeInfo);
78  if (!m_class)
79  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
80  "No ROOT class registered for " + type.Name());
81  } else if (type.IsFundamental()) {
82  if (!m_arraySize)
83  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
84  "Only arrays of primitive types supported. "
85  "Please to not use a Blob for this member.");
86 
88  type.TypeInfo()) - primitives;
89  if (m_primitive >= nPrimitives)
90  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
91  "Cannot handle primitive type " + type.Name());
92  } else
93  throw cond::Exception("TBufferBlobTypeInfo::TBufferBlobTypeInfo "
94  "Cannot handle C++ type " + type.Name());
95 }
96 
97 
99 }
100 
102 }
103 
104 #include <boost/bind.hpp>
105 namespace {
106  char * reallocInBlob( boost::shared_ptr<coral::Blob> theBlob, char* p, size_t newsize, size_t oldsize) {
107  // various checks missing....
108  theBlob->resize(newsize);
109  return (char*)theBlob->startingAddress();
110 
111  }
112 }
113 
114 boost::shared_ptr<coral::Blob> cond::TBufferBlobStreamingService::write( const void* addr,
115  Reflex::Type const & classDictionary,
116  bool ){
117  TBufferBlobTypeInfo theType( classDictionary );
118  if (theType.m_class && theType.m_class->GetActualClass(addr) != theType.m_class)
119  throw cond::Exception("TBufferBlobWriter::write object to stream is "
120  "not of actual class.");
121 
122  boost::shared_ptr<coral::Blob> theBlob( new coral::Blob );
123  //theBlob->resize(1024);
124 
125  // with new root...
126  // TBufferFile buffer(TBufferFile::kWrite, theBlob->size(), theBlob->startingAddress(), kFALSE, boost::bind(reallocInBlob, theBlob,_1,_2,_3));
127  TBufferFile buffer(TBufferFile::kWrite);
128  buffer.InitMap();
129 
130  if (theType.m_arraySize && !theType.m_class)
131  (buffer.*primitives[theType.m_primitive].writeArrayFn)(addr, theType.m_arraySize);
132  else if (theType.m_arraySize)
133  buffer.WriteFastArray(const_cast<void*>(addr), theType.m_class, theType.m_arraySize);
134  else
135  buffer.StreamObject(const_cast<void*>(addr), theType.m_class);
136 
137  Int_t size = buffer.Length();
138 
139  theBlob->resize(size);
140  void *startingAddress = theBlob->startingAddress();
141  std::memcpy(startingAddress, buffer.Buffer(), size);
142 
143  return theBlob;
144 }
145 
146 void cond::TBufferBlobStreamingService::read( const coral::Blob& blobData,
147  void* addr,
148  Reflex::Type const & classDictionary ){
149  TBufferBlobTypeInfo theType( classDictionary );
150  const void *startingAddress = blobData.startingAddress();
151  size_t size = blobData.size();
152  if (!size)
153  return;
154 
155  TBufferFile buffer(TBufferFile::kRead, size,
156  const_cast<void*>(startingAddress), kFALSE);
157 
158  buffer.InitMap();
159 
160  if (theType.m_arraySize && !theType.m_class)
161  (buffer.*primitives[theType.m_primitive].readArrayFn)(addr, theType.m_arraySize);
162  else if (theType.m_arraySize)
163  buffer.ReadFastArray(addr, theType.m_class, theType.m_arraySize);
164  else
165  buffer.StreamObject(addr, theType.m_class);
166 }
167 
type
Definition: HCALResponse.h:21
std::size_t m_arraySize
length of the plain C array (zero otherwise)
#define PRIMITIVE(x)
TClass * m_class
The class as seen by the ROOT streaming services.
void read(const coral::Blob &blobData, void *addressOfContainer, Reflex::Type const &classDictionary)
Reads an object from a Blob and fills-in the container.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
unsigned int m_primitive
the primitive C++ type if m_class is unset
const std::type_info & type
TBufferBlobTypeInfo(const Reflex::Type &type)
boost::shared_ptr< coral::Blob > write(const void *addressOfInputData, Reflex::Type const &classDictionary, bool useCompression=false)
void(TBuffer::* ReadArrayFn_t)(void *obj, Int_t n)
static const std::size_t nPrimitives
ReadArrayFn_t readArrayFn
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