add deserializeFrom* helpers

This commit is contained in:
Michael Davidsaver
2016-02-05 17:40:24 -05:00
parent 85a1a48b00
commit e35c6f29fb
3 changed files with 99 additions and 1 deletions

View File

@@ -164,6 +164,24 @@ namespace epics { namespace pvData {
int byteOrder,
std::vector<epicsUInt8>& out);
/**
* @brief deserializeFromBuffer Deserialize into S from provided vector
* @param S A Serializeable object. The current contents will be replaced
* @param byteOrder Byte order to write (EPICS_ENDIAN_LITTLE or EPICS_ENDIAN_BIG)
* @param in The input buffer (byte order of this buffer is used)
* @throws std::logic_error if input buffer is too small. State of S is then undefined.
*/
void deserializeFromBuffer(Serializable *S,
ByteBuffer& in);
inline void deserializeFromVector(Serializable *S,
int byteOrder,
const std::vector<epicsUInt8>& in)
{
ByteBuffer B((char*)&in[0], in.size(), byteOrder); // we promise not the modify 'in'
deserializeFromBuffer(S, B);
}
/**
* @brief Class for serializing bitSets.
*

View File

@@ -215,3 +215,57 @@ namespace epics {
}
}
}
namespace {
struct FromString : public epics::pvData::DeserializableControl
{
ByteBuffer &buf;
epics::pvData::FieldCreatePtr create;
FromString(ByteBuffer& b)
:buf(b)
,create(epics::pvData::getFieldCreate())
{}
virtual void ensureData(std::size_t size)
{
if(size>buf.getRemaining())
throw std::logic_error("Incomplete buffer");
}
virtual void alignData(std::size_t alignment)
{
size_t pos = buf.getPosition(), k = alignment-1;
if(pos&k) {
std::size_t npad = alignment-(pos&k);
ensureData(npad);
buf.align(alignment);
}
}
virtual bool directDeserialize(
ByteBuffer *existingBuffer,
char* deserializeTo,
std::size_t elementCount,
std::size_t elementSize)
{
return false;
}
virtual std::tr1::shared_ptr<const Field> cachedDeserialize(
ByteBuffer* buffer)
{
return create->deserialize(buffer, this);
}
};
}
namespace epics {
namespace pvData {
void deserializeFromBuffer(Serializable *S,
ByteBuffer& buf)
{
FromString F(buf);
S->deserialize(&buf, &F);
}
}
}

View File

@@ -834,11 +834,35 @@ void testToString(int byteOrder)
printbytes(bytes.size(), &bytes[0]);
}
void testFromString(int byteOrder)
{
testDiag("testFromString(%d)", byteOrder);
StructureConstPtr _type = getFieldCreate()->createFieldBuilder()
->add("X", pvInt)->add("Y", pvString)
->createStructure();
PVStructurePtr _data = getPVDataCreate()->createPVStructure(_type);
if(byteOrder==EPICS_ENDIAN_LITTLE) {
ByteBuffer buf((char*)expected_le, NELEMENTS(expected_le)-1, byteOrder);
deserializeFromBuffer(_data.get(), buf);
} else if(byteOrder==EPICS_ENDIAN_BIG) {
ByteBuffer buf((char*)expected_be, NELEMENTS(expected_be)-1, byteOrder);
deserializeFromBuffer(_data.get(), buf);
} else {
throw std::logic_error("Unsupported mixed endian");
}
testOk1(_data->getSubFieldT<PVInt>("X")->get()==42);
testOk1(_data->getSubFieldT<PVString>("Y")->get()=="testing");
}
} // end namespace
MAIN(testSerialization) {
testPlan(230);
testPlan(234);
flusher = new SerializableControlImpl();
control = new DeserializableControlImpl();
@@ -862,6 +886,8 @@ MAIN(testSerialization) {
testToString(EPICS_ENDIAN_BIG);
testToString(EPICS_ENDIAN_LITTLE);
testFromString(EPICS_ENDIAN_BIG);
testFromString(EPICS_ENDIAN_LITTLE);
delete buffer;
delete control;