Field serialization moved to pvData
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <pv/convert.h>
|
||||
#include <pv/factory.h>
|
||||
#include <pv/CDRMonitor.h>
|
||||
#include <pv/serializeHelper.h>
|
||||
|
||||
using std::tr1::static_pointer_cast;
|
||||
|
||||
@@ -61,6 +62,53 @@ void Scalar::toString(StringBuilder buffer,int indentLevel) const{
|
||||
Field::toString(buffer,indentLevel);
|
||||
}
|
||||
|
||||
void Scalar::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)(epics::pvData::scalar << 4 | getScalarType()));
|
||||
SerializeHelper::serializeString(getFieldName(), buffer, control);
|
||||
}
|
||||
|
||||
void Scalar::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void serializeStructureField(const Structure* structure, ByteBuffer* buffer, SerializableControl* control)
|
||||
{
|
||||
SerializeHelper::serializeString(structure->getFieldName(), buffer, control);
|
||||
FieldConstPtrArray fields = structure->getFields();
|
||||
SerializeHelper::writeSize(structure->getNumberFields(), buffer, control);
|
||||
for (int i = 0; i < structure->getNumberFields(); i++)
|
||||
{
|
||||
control->cachedSerialize(fields[i], buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static StructureConstPtr deserializeStructureField(const FieldCreate* fieldCreate, ByteBuffer* buffer, DeserializableControl* control)
|
||||
{
|
||||
const String structureFieldName = SerializeHelper::deserializeString(buffer, control);
|
||||
const int32 size = SerializeHelper::readSize(buffer, control);
|
||||
FieldConstPtrArray fields = NULL;
|
||||
if (size > 0)
|
||||
{
|
||||
fields = new FieldConstPtr[size];
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
try {
|
||||
fields[i] = control->cachedDeserialize(buffer);
|
||||
} catch (...) {
|
||||
delete[] fields;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StructureConstPtr structure = fieldCreate->createStructure(structureFieldName, size, fields);
|
||||
return structure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ScalarArray::ScalarArray(String fieldName,ScalarType elementType)
|
||||
: Field(fieldName,scalarArray),elementType(elementType){}
|
||||
@@ -73,6 +121,15 @@ void ScalarArray::toString(StringBuilder buffer,int indentLevel) const{
|
||||
Field::toString(buffer,indentLevel);
|
||||
}
|
||||
|
||||
void ScalarArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)(epics::pvData::scalarArray << 4 | getElementType()));
|
||||
SerializeHelper::serializeString(getFieldName(), buffer, control);
|
||||
}
|
||||
|
||||
void ScalarArray::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
}
|
||||
|
||||
StructureArray::StructureArray(String fieldName,StructureConstPtr structure)
|
||||
: Field(fieldName,structureArray),pstructure(structure)
|
||||
{
|
||||
@@ -89,6 +146,17 @@ void StructureArray::toString(StringBuilder buffer,int indentLevel) const {
|
||||
pstructure->toString(buffer,indentLevel + 1);
|
||||
}
|
||||
|
||||
void StructureArray::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)(epics::pvData::structureArray << 4));
|
||||
SerializeHelper::serializeString(getFieldName(), buffer, control);
|
||||
// we also need to serialize structure field...
|
||||
serializeStructureField(getStructure().get(), buffer, control);
|
||||
}
|
||||
|
||||
void StructureArray::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
}
|
||||
|
||||
|
||||
Structure::Structure (String fieldName,
|
||||
int numberFields, FieldConstPtrArray infields)
|
||||
@@ -186,6 +254,14 @@ void Structure::toString(StringBuilder buffer,int indentLevel) const{
|
||||
}
|
||||
}
|
||||
|
||||
void Structure::serialize(ByteBuffer *buffer, SerializableControl *control) const {
|
||||
control->ensureBuffer(1);
|
||||
buffer->putByte((int8)(epics::pvData::structure << 4));
|
||||
serializeStructureField(this, buffer, control);
|
||||
}
|
||||
|
||||
void Structure::deserialize(ByteBuffer *buffer, DeserializableControl *control) {
|
||||
}
|
||||
|
||||
ScalarConstPtr FieldCreate::createScalar(String fieldName,
|
||||
ScalarType scalarType) const
|
||||
@@ -243,6 +319,45 @@ FieldConstPtr FieldCreate::create(String fieldName,
|
||||
THROW_EXCEPTION2(std::logic_error, message);
|
||||
}
|
||||
|
||||
FieldConstPtr FieldCreate::deserialize(ByteBuffer* buffer, DeserializableControl* control) const
|
||||
{
|
||||
control->ensureData(1);
|
||||
const int8 typeCode = buffer->getByte();
|
||||
|
||||
// high nibble means scalar/array/structure
|
||||
const Type type = (Type)(typeCode >> 4);
|
||||
switch (type)
|
||||
{
|
||||
case scalar:
|
||||
{
|
||||
const ScalarType scalar = (ScalarType)(typeCode & 0x0F);
|
||||
const String scalarFieldName = SerializeHelper::deserializeString(buffer, control);
|
||||
return static_cast<FieldConstPtr>(createScalar(scalarFieldName,scalar));
|
||||
}
|
||||
case scalarArray:
|
||||
{
|
||||
const ScalarType element = (ScalarType)(typeCode & 0x0F);
|
||||
const String arrayFieldName = SerializeHelper::deserializeString(buffer, control);
|
||||
return static_cast<FieldConstPtr>(createScalarArray(arrayFieldName,element));
|
||||
}
|
||||
case structure:
|
||||
{
|
||||
return static_cast<FieldConstPtr>(deserializeStructureField(this, buffer, control));
|
||||
}
|
||||
case structureArray:
|
||||
{
|
||||
const String structureArrayFieldName = SerializeHelper::deserializeString(buffer, control);
|
||||
const StructureConstPtr arrayElement = deserializeStructureField(this, buffer, control);
|
||||
return static_cast<FieldConstPtr>(createStructureArray(structureArrayFieldName, arrayElement));
|
||||
}
|
||||
default:
|
||||
{
|
||||
// TODO log
|
||||
return FieldConstPtr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static FieldCreate* fieldCreate = 0;
|
||||
|
||||
FieldCreate::FieldCreate()
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#ifndef SERIALIZE_H
|
||||
#define SERIALIZE_H
|
||||
#include <pv/byteBuffer.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class SerializableControl;
|
||||
@@ -15,6 +16,7 @@ namespace epics { namespace pvData {
|
||||
class BitSetSerializable;
|
||||
class SerializableArray;
|
||||
class BitSet;
|
||||
class Field;
|
||||
|
||||
class SerializableControl {
|
||||
public:
|
||||
@@ -22,6 +24,7 @@ namespace epics { namespace pvData {
|
||||
virtual void flushSerializeBuffer() =0;
|
||||
virtual void ensureBuffer(int size) =0;
|
||||
virtual void alignBuffer(int alignment) =0;
|
||||
virtual void cachedSerialize(std::tr1::shared_ptr<const Field> const & field, ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
class DeserializableControl {
|
||||
@@ -29,6 +32,7 @@ namespace epics { namespace pvData {
|
||||
virtual ~DeserializableControl(){}
|
||||
virtual void ensureData(int size) =0;
|
||||
virtual void alignData(int alignment) =0;
|
||||
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer) = 0;
|
||||
};
|
||||
|
||||
class Serializable {
|
||||
|
||||
@@ -13,6 +13,9 @@
|
||||
#include <pv/noDefaultMethods.h>
|
||||
#include <pv/sharedPtr.h>
|
||||
#include <pv/pvType.h>
|
||||
#include <pv/byteBuffer.h>
|
||||
#include <pv/serialize.h>
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Field;
|
||||
@@ -170,7 +173,9 @@ namespace ScalarTypeFunc {
|
||||
/**
|
||||
* This class implements introspection object for field.
|
||||
*/
|
||||
class Field : public std::tr1::enable_shared_from_this<Field> {
|
||||
class Field :
|
||||
virtual public Serializable,
|
||||
public std::tr1::enable_shared_from_this<Field> {
|
||||
public:
|
||||
POINTER_DEFINITIONS(Field);
|
||||
/**
|
||||
@@ -254,6 +259,10 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
|
||||
|
||||
protected:
|
||||
Scalar(String fieldName,ScalarType scalarType);
|
||||
private:
|
||||
@@ -287,6 +296,10 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Destructor.
|
||||
@@ -319,6 +332,10 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel=0) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -398,6 +415,10 @@ public:
|
||||
* @param indentLevel The number of blanks at the beginning of new lines.
|
||||
*/
|
||||
virtual void toString(StringBuilder buf,int indentLevel) const;
|
||||
|
||||
virtual void serialize(ByteBuffer *buffer, SerializableControl *flusher) const;
|
||||
virtual void deserialize(ByteBuffer *buffer, DeserializableControl *flusher);
|
||||
|
||||
protected:
|
||||
Structure(String fieldName, int numberFields,FieldConstPtrArray fields);
|
||||
private:
|
||||
@@ -450,6 +471,15 @@ public:
|
||||
*/
|
||||
StructureArrayConstPtr createStructureArray(String fieldName,
|
||||
StructureConstPtr structure) const;
|
||||
|
||||
/**
|
||||
* Deserialize {@code Field} instance from given byte buffer.
|
||||
* @param buffer Buffer containing serialized {@code Field} instance.
|
||||
* @param control Deserialization control instance.
|
||||
* @return a deserialized {@code Field} instance.
|
||||
*/
|
||||
FieldConstPtr deserialize(ByteBuffer* buffer, DeserializableControl* control) const;
|
||||
|
||||
private:
|
||||
FieldCreate();
|
||||
friend FieldCreate * getFieldCreate();
|
||||
|
||||
@@ -55,6 +55,11 @@ public:
|
||||
virtual void alignBuffer(int alignment) {
|
||||
buffer->align(alignment);
|
||||
}
|
||||
|
||||
virtual void cachedSerialize(std::tr1::shared_ptr<const Field> const & field, ByteBuffer* buffer)
|
||||
{
|
||||
field->serialize(buffer, this);
|
||||
}
|
||||
|
||||
SerializableControlImpl() {
|
||||
}
|
||||
@@ -73,6 +78,11 @@ public:
|
||||
buffer->align(alignment);
|
||||
}
|
||||
|
||||
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(ByteBuffer* buffer)
|
||||
{
|
||||
return getFieldCreate()->deserialize(buffer, this);
|
||||
}
|
||||
|
||||
DeserializableControlImpl() {
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user