Field serialization moved to pvData

This commit is contained in:
Matej Sekoranja
2012-03-27 10:32:37 +02:00
parent 198562c36c
commit 6caa725f5a
4 changed files with 160 additions and 1 deletions

View File

@@ -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()

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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() {
}