Skip to content

Commit d23e09a

Browse files
committed
CmwLightSerialiser: fix handling of empty nested objects/maps
1 parent 482b67a commit d23e09a

File tree

2 files changed

+137
-5
lines changed

2 files changed

+137
-5
lines changed

src/serialiser/include/IoSerialiserCmwLight.hpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,6 @@ struct IoSerialiser<CmwLight, START_MARKER> {
242242
}
243243

244244
constexpr static void deserialise(IoBuffer & buffer, FieldDescription auto & field, const START_MARKER &) {
245-
if (field.hierarchyDepth > 0) {
246-
std::ignore = buffer.get<uint8_t>(); // skip the field type byte which has already been processed
247-
}
248245
field.subfields = buffer.get<int32_t>();
249246
field.dataStartPosition = buffer.position();
250247
}
@@ -339,16 +336,18 @@ struct FieldHeaderReader<CmwLight> {
339336
field.dataEndPosition = std::numeric_limits<size_t>::max();
340337
field.modifier = ExternalModifier::UNKNOWN;
341338
if (field.subfields == 0) {
339+
field.dataStartPosition = field.headerStart + (field.intDataType ==IoSerialiser<CmwLight, START_MARKER>::getDataTypeId() ? 4 : 0 );
342340
field.intDataType = IoSerialiser<CmwLight, END_MARKER>::getDataTypeId();
343341
field.hierarchyDepth--;
344-
field.dataStartPosition = buffer.position();
345342
return;
346343
}
347344
if (field.subfields == -1) {
348345
if (field.hierarchyDepth != 0) { // do not read field description for root element
349346
field.fieldName = buffer.get<std::string_view>(); // full field name
347+
field.intDataType = buffer.get<uint8_t>(); // data type ID
348+
} else {
349+
field.intDataType = IoSerialiser<CmwLight, START_MARKER>::getDataTypeId();
350350
}
351-
field.intDataType = IoSerialiser<CmwLight, START_MARKER>::getDataTypeId();
352351
} else {
353352
field.fieldName = buffer.get<std::string_view>(); // full field name
354353
field.intDataType = buffer.get<uint8_t>(); // data type ID

src/serialiser/test/IoSerialiserCmwLight_tests.cpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,136 @@ TEST_CASE("IoClassSerialiserCmwLight deserialise into map", "[IoClassSerialiser]
312312
REQUIRE(opencmw::debug::dealloc == opencmw::debug::alloc); // a memory leak occurred
313313
debug::resetStats();
314314
}
315+
316+
namespace opencmw::serialiser::cmwlighttests {
317+
struct CmwLightHeaderOptions {
318+
int64_t b; // SOURCE_ID
319+
std::map<std::string, std::string> e;
320+
// can potentially contain more and arbitrary data
321+
// accessors to make code more readable
322+
int64_t &sourceId() {return b;}
323+
std::map<std::string, std::string> sessionBody;
324+
};
325+
struct CmwLightHeader {
326+
int8_t x_2; // REQ_TYPE_TAG
327+
int64_t x_0; // ID_TAG
328+
std::string x_1; // DEVICE_NAME
329+
std::string f; // PROPERTY_NAME
330+
int8_t x_7; // UPDATE_TYPE
331+
std::string d; // SESSION_ID
332+
std::unique_ptr<CmwLightHeaderOptions> x_3;
333+
// accessors to make code more readable
334+
int8_t &requestType(){return x_2;}
335+
int64_t &id() {return x_0;}
336+
std::string &device() {return x_1;}
337+
std::string &property() {return f;}
338+
int8_t &updateType() {return x_7;}
339+
std::string &sessionId() {return d;}
340+
std::unique_ptr<CmwLightHeaderOptions> &options() {return x_3;}
341+
};
342+
struct DigitizerVersion {
343+
std::string classVersion;
344+
std::string deployUnitVersion;
345+
std::string fesaVersion;
346+
std::string gr_flowgraph_version;
347+
std::string gr_digitizer_version;
348+
std::string daqAPIVersion;
349+
};
350+
}
351+
ENABLE_REFLECTION_FOR(opencmw::serialiser::cmwlighttests::CmwLightHeaderOptions, b, e)
352+
ENABLE_REFLECTION_FOR(opencmw::serialiser::cmwlighttests::CmwLightHeader, x_2, x_0, x_1, f, x_7, d, x_3)
353+
ENABLE_REFLECTION_FOR(opencmw::serialiser::cmwlighttests::DigitizerVersion, classVersion, deployUnitVersion , fesaVersion , gr_flowgraph_version, gr_digitizer_version, daqAPIVersion)
354+
355+
TEST_CASE("IoClassSerialiserCmwLight Deserialise rda3 data", "[IoClassSerialiser]") {
356+
// ensure that important rda3 messages can be properly deserialized
357+
using namespace opencmw;
358+
debug::resetStats();
359+
using namespace opencmw::serialiser::cmwlighttests;
360+
{
361+
std::string_view rda3ConnectReply = "\x07\x00\x00\x00\x02\x00\x00\x00\x30\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x31\x00\x07\x01\x00\x00\x00\x00\x02\x00\x00\x00\x32\x00\x01\x03\x02\x00\x00\x00\x33\x00\x08\x02\x00\x00\x00\x02\x00\x00\x00\x62\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x65\x00\x08\x00\x00\x00\x00\x02\x00\x00\x00\x37\x00\x01\x70\x02\x00\x00\x00\x64\x00\x07\x01\x00\x00\x00\x00\x02\x00\x00\x00\x66\x00\x07\x01\x00\x00\x00\x00"sv;
362+
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
363+
// 000 "\x07\x00\x00\x00\x02\x00\x00\x00" "\x30\x00\x04\x00\x00\x00\x00\x00"
364+
// 010 "\x00\x00\x00\x02\x00\x00\x00\x31" "\x00\x07\x01\x00\x00\x00\x00\x02"
365+
// 020 "\x00\x00\x00\x32\x00\x01\x03\x02" "\x00\x00\x00\x33\x00\x08\x02\x00"
366+
// 030 "\x00\x00\x02\x00\x00\x00\x62\x00" "\x04\x00\x00\x00\x00\x00\x00\x00"
367+
// 040 "\x00\x02\x00\x00\x00\x65\x00\x08" "\x00\x00\x00\x00\x02\x00\x00\x00"
368+
// 050 "\x37\x00\x01\x70\x02\x00\x00\x00" "\x64\x00\x07\x01\x00\x00\x00\x00"
369+
// 060 "\x02\x00\x00\x00\x66\x00\x07\x01" "\x00\x00\x00\x00"sv
370+
IoBuffer buffer{ rda3ConnectReply.data(), rda3ConnectReply.size() };
371+
CmwLightHeader deserialised;
372+
auto result = opencmw::deserialise<CmwLight, opencmw::ProtocolCheck::LENIENT>(buffer, deserialised);
373+
374+
REQUIRE(deserialised.requestType() == 3);
375+
REQUIRE(deserialised.id() == 0);
376+
REQUIRE(deserialised.device().empty());
377+
REQUIRE(deserialised.property().empty());
378+
REQUIRE(deserialised.updateType() == 0x70);
379+
REQUIRE(deserialised.sessionId().empty());
380+
REQUIRE(deserialised.options()->sourceId() == 0);
381+
REQUIRE(deserialised.options()->sessionBody.empty());
382+
}{
383+
std::string_view data = "\x07\x00\x00\x00\x02\x00\x00\x00\x30\x00\x04\x09\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x31\x00\x07\x08\x00\x00\x00\x47\x53\x43\x44\x30\x30\x32\x00\x02\x00\x00\x00\x32\x00\x01\x0b\x02\x00\x00\x00\x33\x00\x08\x01\x00\x00\x00\x02\x00\x00\x00\x65\x00\x08\x00\x00\x00\x00\x02\x00\x00\x00\x37\x00\x01\x00\x02\x00\x00\x00\x64\x00\x07\x25\x01\x00\x00\x52\x65\x6d\x6f\x74\x65\x48\x6f\x73\x74\x49\x6e\x66\x6f\x49\x6d\x70\x6c\x5b\x6e\x61\x6d\x65\x3d\x66\x65\x73\x61\x2d\x65\x78\x70\x6c\x6f\x72\x65\x72\x2d\x61\x70\x70\x3b\x20\x75\x73\x65\x72\x4e\x61\x6d\x65\x3d\x61\x6b\x72\x69\x6d\x6d\x3b\x20\x61\x70\x70\x49\x64\x3d\x5b\x61\x70\x70\x3d\x66\x65\x73\x61\x2d\x65\x78\x70\x6c\x6f\x72\x65\x72\x2d\x61\x70\x70\x3b\x76\x65\x72\x3d\x31\x39\x2e\x30\x2e\x30\x3b\x75\x69\x64\x3d\x61\x6b\x72\x69\x6d\x6d\x3b\x68\x6f\x73\x74\x3d\x53\x59\x53\x50\x43\x30\x30\x38\x3b\x70\x69\x64\x3d\x31\x39\x31\x36\x31\x36\x3b\x5d\x3b\x20\x70\x72\x6f\x63\x65\x73\x73\x3d\x66\x65\x73\x61\x2d\x65\x78\x70\x6c\x6f\x72\x65\x72\x2d\x61\x70\x70\x3b\x20\x70\x69\x64\x3d\x31\x39\x31\x36\x31\x36\x3b\x20\x61\x64\x64\x72\x65\x73\x73\x3d\x74\x63\x70\x3a\x2f\x2f\x53\x59\x53\x50\x43\x30\x30\x38\x3a\x30\x3b\x20\x73\x74\x61\x72\x74\x54\x69\x6d\x65\x3d\x32\x30\x32\x34\x2d\x30\x37\x2d\x30\x34\x20\x31\x31\x3a\x31\x31\x3a\x31\x32\x3b\x20\x63\x6f\x6e\x6e\x65\x63\x74\x69\x6f\x6e\x54\x69\x6d\x65\x3d\x41\x62\x6f\x75\x74\x20\x61\x67\x6f\x3b\x20\x76\x65\x72\x73\x69\x6f\x6e\x3d\x31\x30\x2e\x33\x2e\x30\x3b\x20\x6c\x61\x6e\x67\x75\x61\x67\x65\x3d\x4a\x61\x76\x61\x5d\x31\x00\x02\x00\x00\x00\x66\x00\x07\x08\x00\x00\x00\x56\x65\x72\x73\x69\x6f\x6e\x00"sv;
384+
// reply req type: session confirm
385+
// \x07 \x00 \x00 \x00 ....
386+
// \x02 \x00 \x00 \x00 \x30 \x00 \x04 \x09 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x02 ....0... ........
387+
// \x00 \x00 \x00 \x31 \x00 \x07 \x08 \x00 \x00 \x00 \x47 \x53 \x43 \x44 \x30 \x30 ...1.... ..GSCD00
388+
// \x32 \x00 \x02 \x00 \x00 \x00 \x32 \x00 \x01 \x0b \x02 \x00 \x00 \x00 \x33 \x00 2.....2. ......3.
389+
// \x08 \x01 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x65 \x00 \x08 \x00 \x00 \x00 \x00 ........ .e......
390+
// \x02 \x00 \x00 \x00 \x37 \x00 \x01 \x00 \x02 \x00 \x00 \x00 \x64 \x00 \x07 \x25 ....7... ....d..%
391+
// \x01 \x00 \x00 \x52 \x65 \x6d \x6f \x74 \x65 \x48 \x6f \x73 \x74 \x49 \x6e \x66 ...Remot eHostInf
392+
// \x6f \x49 \x6d \x70 \x6c \x5b \x6e \x61 \x6d \x65 \x3d \x66 \x65 \x73 \x61 \x2d oImpl[na me=fesa-
393+
// \x65 \x78 \x70 \x6c \x6f \x72 \x65 \x72 \x2d \x61 \x70 \x70 \x3b \x20 \x75 \x73 explorer -app; us
394+
// \x65 \x72 \x4e \x61 \x6d \x65 \x3d \x61 \x6b \x72 \x69 \x6d \x6d \x3b \x20 \x61 erName=a krimm; a
395+
// \x70 \x70 \x49 \x64 \x3d \x5b \x61 \x70 \x70 \x3d \x66 \x65 \x73 \x61 \x2d \x65 ppId=[ap p=fesa-e
396+
// \x78 \x70 \x6c \x6f \x72 \x65 \x72 \x2d \x61 \x70 \x70 \x3b \x76 \x65 \x72 \x3d xplorer- app;ver=
397+
// \x31 \x39 \x2e \x30 \x2e \x30 \x3b \x75 \x69 \x64 \x3d \x61 \x6b \x72 \x69 \x6d 19.0.0;u id=akrim
398+
// \x6d \x3b \x68 \x6f \x73 \x74 \x3d \x53 \x59 \x53 \x50 \x43 \x30 \x30 \x38 \x3b m;host=S YSPC008;
399+
// \x70 \x69 \x64 \x3d \x31 \x39 \x31 \x36 \x31 \x36 \x3b \x5d \x3b \x20 \x70 \x72 pid=1916 16;]; pr
400+
// \x6f \x63 \x65 \x73 \x73 \x3d \x66 \x65 \x73 \x61 \x2d \x65 \x78 \x70 \x6c \x6f ocess=fe sa-explo
401+
// \x72 \x65 \x72 \x2d \x61 \x70 \x70 \x3b \x20 \x70 \x69 \x64 \x3d \x31 \x39 \x31 rer-app; pid=191
402+
// \x36 \x31 \x36 \x3b \x20 \x61 \x64 \x64 \x72 \x65 \x73 \x73 \x3d \x74 \x63 \x70 616; add ress=tcp
403+
// \x3a \x2f \x2f \x53 \x59 \x53 \x50 \x43 \x30 \x30 \x38 \x3a \x30 \x3b \x20 \x73 ://SYSPC 008:0; s
404+
// \x74 \x61 \x72 \x74 \x54 \x69 \x6d \x65 \x3d \x32 \x30 \x32 \x34 \x2d \x30 \x37 tartTime =2024-07
405+
// \x2d \x30 \x34 \x20 \x31 \x31 \x3a \x31 \x31 \x3a \x31 \x32 \x3b \x20 \x63 \x6f -04 11:1 1:12; co
406+
// \x6e \x6e \x65 \x63 \x74 \x69 \x6f \x6e \x54 \x69 \x6d \x65 \x3d \x41 \x62 \x6f nnection Time=Abo
407+
// \x75 \x74 \x20 \x61 \x67 \x6f \x3b \x20 \x76 \x65 \x72 \x73 \x69 \x6f \x6e \x3d ut ago; version=
408+
// \x31 \x30 \x2e \x33 \x2e \x30 \x3b \x20 \x6c \x61 \x6e \x67 \x75 \x61 \x67 \x65 10.3.0; language
409+
// \x3d \x4a \x61 \x76 \x61 \x5d \x31 \x00 \x02 \x00 \x00 \x00 \x66 \x00 \x07 \x08 =Java]1. ....f...
410+
// \x00 \x00 \x00 \x56 \x65 \x72 \x73 \x69 \x6f \x6e \x00 ...Versi on.
411+
IoBuffer buffer{ data.data(), data.size() };
412+
CmwLightHeader deserialised;
413+
auto result = opencmw::deserialise<CmwLight, opencmw::ProtocolCheck::LENIENT>(buffer, deserialised);
414+
} {
415+
std::string_view data = "\x06\x00\x00\x00\x02\x00\x00\x00\x30\x00\x04\x09\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x31\x00\x07\x01\x00\x00\x00\x00\x02\x00\x00\x00\x32\x00\x01\x03\x02\x00\x00\x00\x37\x00\x01\x00\x02\x00\x00\x00\x64\x00\x07\x01\x00\x00\x00\x00\x02\x00\x00\x00\x66\x00\x07\x01\x00\x00\x00\x00\x01\xc3\x06\x00\x00\x00\x0d\x00\x00\x00\x63\x6c\x61\x73\x73\x56\x65\x72\x73\x69\x6f\x6e\x00\x07\x06\x00\x00\x00\x36\x2e\x30\x2e\x30\x00\x0e\x00\x00\x00\x64\x61\x71\x41\x50\x49\x56\x65\x72\x73\x69\x6f\x6e\x00\x07\x04\x00\x00\x00\x32\x2e\x30\x00\x12\x00\x00\x00\x64\x65\x70\x6c\x6f\x79\x55\x6e\x69\x74\x56\x65\x72\x73\x69\x6f\x6e\x00\x07\x06\x00\x00\x00\x36\x2e\x30\x2e\x30\x00\x0c\x00\x00\x00\x66\x65\x73\x61\x56\x65\x72\x73\x69\x6f\x6e\x00\x07\x06\x00\x00\x00\x37\x2e\x33\x2e\x30\x00\x15\x00\x00\x00\x67\x72\x5f\x64\x69\x67\x69\x74\x69\x7a\x65\x72\x5f\x76\x65\x72\x73\x69\x6f\x6e\x00\x07\x08\x00\x00\x00\x35\x2e\x31\x2e\x34\x2e\x30\x00\x15\x00\x00\x00\x67\x72\x5f\x66\x6c\x6f\x77\x67\x72\x61\x70\x68\x5f\x76\x65\x72\x73\x69\x6f\x6e\x00\x07\x08\x00\x00\x00\x35\x2e\x30\x2e\x32\x2e\x30\x00\x01\x62\x03\x00\x00\x00\x02\x00\x00\x00\x35\x00\x04\x88\x39\xfe\x41\x88\xf7\xde\x17\x02\x00\x00\x00\x36\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x78\x00\x08\x03\x00\x00\x00\x09\x00\x00\x00\x61\x63\x71\x53\x74\x61\x6d\x70\x00\x04\x88\x39\xfe\x41\x88\xf7\xde\x17\x05\x00\x00\x00\x74\x79\x70\x65\x00\x03\x02\x00\x00\x00\x08\x00\x00\x00\x76\x65\x72\x73\x69\x6f\x6e\x00\x03\x01\x00\x00\x00\x00\x03";
416+
// Reply with Req Type = Reply, gets sent after get request
417+
// \x06 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x30 \x00 \x04 ... .....0..
418+
// \x09 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x31 \x00 \x07 \x01 ........ ....1...
419+
// \x00 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x32 \x00 \x01 \x03 \x02 \x00 \x00 \x00 ........ 2.......
420+
// \x37 \x00 \x01 \x00 \x02 \x00 \x00 \x00 \x64 \x00 \x07 \x01 \x00 \x00 \x00 \x00 7....... d.......
421+
// \x02 \x00 \x00 \x00 \x66 \x00 \x07 \x01 \x00 \x00 \x00 \x00 \x01 \xc3 \x06 \x00 ....f... ........
422+
// \x00 \x00 \x0d \x00 \x00 \x00 \x63 \x6c \x61 \x73 \x73 \x56 \x65 \x72 \x73 \x69 ......cl assVersi
423+
// \x6f \x6e \x00 \x07 \x06 \x00 \x00 \x00 \x36 \x2e \x30 \x2e \x30 \x00 \x0e \x00 on...... 6.0.0...
424+
// \x00 \x00 \x64 \x61 \x71 \x41 \x50 \x49 \x56 \x65 \x72 \x73 \x69 \x6f \x6e \x00 ..daqAPI Version.
425+
// \x07 \x04 \x00 \x00 \x00 \x32 \x2e \x30 \x00 \x12 \x00 \x00 \x00 \x64 \x65 \x70 .....2.0 .....dep
426+
// \x6c \x6f \x79 \x55 \x6e \x69 \x74 \x56 \x65 \x72 \x73 \x69 \x6f \x6e \x00 \x07 loyUnitV ersion..
427+
// \x06 \x00 \x00 \x00 \x36 \x2e \x30 \x2e \x30 \x00 \x0c \x00 \x00 \x00 \x66 \x65 ....6.0. 0.....fe
428+
// \x73 \x61 \x56 \x65 \x72 \x73 \x69 \x6f \x6e \x00 \x07 \x06 \x00 \x00 \x00 \x37 saVersio n......7
429+
// \x2e \x33 \x2e \x30 \x00 \x15 \x00 \x00 \x00 \x67 \x72 \x5f \x64 \x69 \x67 \x69 .3.0.... .gr_digi
430+
// \x74 \x69 \x7a \x65 \x72 \x5f \x76 \x65 \x72 \x73 \x69 \x6f \x6e \x00 \x07 \x08 tizer_ve rsion...
431+
// \x00 \x00 \x00 \x35 \x2e \x31 \x2e \x34 \x2e \x30 \x00 \x15 \x00 \x00 \x00 \x67 ...5.1.4 .0.....g
432+
// \x72 \x5f \x66 \x6c \x6f \x77 \x67 \x72 \x61 \x70 \x68 \x5f \x76 \x65 \x72 \x73 r_flowgr aph_vers
433+
// \x69 \x6f \x6e \x00 \x07 \x08 \x00 \x00 \x00 \x35 \x2e \x30 \x2e \x32 \x2e \x30 ion..... .5.0.2.0
434+
// \x00 \x01 \x62 \x03 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x35 \x00 \x04 \x88 \x39 ..b..... ...5...9
435+
// \xfe \x41 \x88 \xf7 \xde \x17 \x02 \x00 \x00 \x00 \x36 \x00 \x04 \x00 \x00 \x00 .A...... ..6.....
436+
// \x00 \x00 \x00 \x00 \x00 \x02 \x00 \x00 \x00 \x78 \x00 \x08 \x03 \x00 \x00 \x00 ........ .x......
437+
// \x09 \x00 \x00 \x00 \x61 \x63 \x71 \x53 \x74 \x61 \x6d \x70 \x00 \x04 \x88 \x39 ....acqS tamp...9
438+
// \xfe \x41 \x88 \xf7 \xde \x17 \x05 \x00 \x00 \x00 \x74 \x79 \x70 \x65 \x00 \x03 .A...... ..type..
439+
// \x02 \x00 \x00 \x00 \x08 \x00 \x00 \x00 \x76 \x65 \x72 \x73 \x69 \x6f \x6e \x00 ........ version.
440+
// \x03 \x01 \x00 \x00 \x00 \x00 \x03 .......
441+
IoBuffer buffer{ data.data(), data.size() };
442+
DigitizerVersion deserialised;
443+
auto result = opencmw::deserialise<CmwLight, opencmw::ProtocolCheck::LENIENT>(buffer, deserialised);
444+
}
445+
REQUIRE(opencmw::debug::dealloc == opencmw::debug::alloc); // a memory leak occurred
446+
debug::resetStats();
447+
}

0 commit comments

Comments
 (0)