This is Unofficial EPICS BASE Doxygen Site
introspectionRegistry.cpp
Go to the documentation of this file.
1 
7 #define epicsExportSharedSymbols
10 
11 using namespace epics::pvData;
12 using namespace std;
14 
15 namespace epics {
16 namespace pvAccess {
17 
18 const int8 IntrospectionRegistry::NULL_TYPE_CODE = (int8)-1;
19 const int8 IntrospectionRegistry::ONLY_ID_TYPE_CODE = (int8)-2;
20 const int8 IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE = (int8)-3;
21 FieldCreatePtr IntrospectionRegistry::_fieldCreate(getFieldCreate());
22 
23 IntrospectionRegistry::IntrospectionRegistry()
24 {
25  reset();
26 }
27 
28 IntrospectionRegistry::~IntrospectionRegistry()
29 {
30  reset();
31 }
32 
33 void IntrospectionRegistry::reset()
34 {
35  _pointer = 1;
36  _registry.clear();
37 }
38 
39 int16 IntrospectionRegistry::registerIntrospectionInterface(FieldConstPtr const & field, bool& existing)
40 {
41  int16 key;
42  // TODO this is slow
43  if(registryContainsValue(field, key))
44  {
45  existing = true;
46  }
47  else
48  {
49  existing = false;
50  key = _pointer++;
51  _registry[key] = field;
52  }
53  return key;
54 }
55 
56 // TODO slow !!!!
57 bool IntrospectionRegistry::registryContainsValue(FieldConstPtr const & field, int16& key)
58 {
59  for(registryMap_t::reverse_iterator registryRIter = _registry.rbegin(); registryRIter != _registry.rend(); registryRIter++)
60  {
61  if(*(field.get()) == *(registryRIter->second))
62  {
63  key = registryRIter->first;
64  return true;
65  }
66  }
67  return false;
68 }
69 
70 void IntrospectionRegistry::serialize(FieldConstPtr const & field, ByteBuffer* buffer, SerializableControl* control)
71 {
72  if (field.get() == NULL)
73  {
74  SerializationHelper::serializeNullField(buffer, control);
75  }
76  else
77  {
78  // do not cache scalars, scalarArrays
79  // ... and (array of) variant unions - not worth the complex condition,
80  // unless bool Field.cache() would exist
81  if (field->getType() != scalar &&
82  field->getType() != scalarArray)
83  {
84  bool existing;
85  const int16 key = registerIntrospectionInterface(field, existing);
86  if (existing) {
87  control->ensureBuffer(3);
88  buffer->putByte(ONLY_ID_TYPE_CODE);
89  buffer->putShort(key);
90  return;
91  }
92  else {
93  control->ensureBuffer(3);
94  buffer->putByte(FULL_WITH_ID_TYPE_CODE); // could also be a mask
95  buffer->putShort(key);
96  }
97  }
98 
99  field->serialize(buffer, control);
100  }
101 }
102 
103 FieldConstPtr IntrospectionRegistry::deserialize(ByteBuffer* buffer, DeserializableControl* control)
104 {
105  control->ensureData(1);
106  size_t pos = buffer->getPosition();
107  const int8 typeCode = buffer->getByte();
108 
109  if (typeCode == NULL_TYPE_CODE)
110  {
111  return FieldConstPtr();
112  }
113  else if (typeCode == ONLY_ID_TYPE_CODE)
114  {
115  control->ensureData(sizeof(int16));
116  int16 id = buffer->getShort();
117 
118  registryMap_t::iterator registryIter = _registry.find(id);
119  if(registryIter == _registry.end())
120  {
121  // peer gave us an id which we don't remember.
122  // This isn't recoverable.
123  throw std::runtime_error("IntrospectionRegistry miss.");
124  }
125  return registryIter->second;
126  }
127  // could also be a mask
128  if(typeCode == IntrospectionRegistry::FULL_WITH_ID_TYPE_CODE)
129  {
130  control->ensureData(sizeof(int16)/sizeof(int8));
131  const short key = buffer->getShort();
132  FieldConstPtr field = _fieldCreate->deserialize(buffer, control);
133  _registry[key] = field;
134  return field;
135  }
136 
137  // return typeCode back
138  buffer->setPosition(pos);
139  return _fieldCreate->deserialize(buffer, control);
140 }
141 
142 }
143 }
int8_t int8
Definition: pvType.h:75
EPICS_ALWAYS_INLINE int8 getByte()
Definition: byteBuffer.h:617
shared_ptr< T > static_pointer_cast(shared_ptr< U > const &r) BOOST_NOEXCEPT
Definition: shared_ptr.hpp:788
Definition: memory.hpp:41
TODO only here because of the Lockable.
Definition: ntaggregate.cpp:16
#define NULL
Definition: catime.c:38
Callback class for deserialization.
Definition: serialize.h:89
std::size_t getPosition() const
Definition: byteBuffer.h:346
void setPosition(std::size_t pos)
Definition: byteBuffer.h:357
pvData
Definition: monitor.h:428
EPICS_ALWAYS_INLINE void putByte(int8 value)
Definition: byteBuffer.h:525
This class implements a Bytebuffer that is like the java.nio.ByteBuffer.
Definition: byteBuffer.h:233
EPICS_ALWAYS_INLINE int16 getShort()
Definition: byteBuffer.h:623
std::tr1::shared_ptr< const Field > FieldConstPtr
Definition: pvIntrospect.h:137
FORCE_INLINE const FieldCreatePtr & getFieldCreate()
std::tr1::shared_ptr< FieldCreate > FieldCreatePtr
virtual void ensureBuffer(std::size_t size)=0
Callback class for serialization.
Definition: serialize.h:34
int16_t int16
Definition: pvType.h:79
virtual void ensureData(std::size_t size)=0
EPICS_ALWAYS_INLINE void putShort(int16 value)
Definition: byteBuffer.h:531