add deserializeFrom* helpers
This commit is contained in:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user