|
| GenericMessage ()=default |
|
| GenericMessage (GenericMessage &&)=default |
|
| GenericMessage (const GenericMessage &)=default |
|
GenericMessage & | operator= (const GenericMessage &)=default |
|
int32_t | ID () |
|
const std::string | ShortName () |
|
const std::string | LongName () |
|
template<typename T > |
void | createFrom (T &msg) |
|
void | createFrom (const MetaMessage &mm, const std::vector< MetaMessage > &mms) noexcept |
|
void | preVisit (int32_t id, const std::string &shortName, const std::string &longName) noexcept |
|
void | postVisit () noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, bool &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, char &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, int8_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, uint8_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, int16_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, uint16_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, int32_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, uint32_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, int64_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, uint64_t &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, float &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, double &v) noexcept |
|
void | visit (uint32_t id, std::string &&typeName, std::string &&name, std::string &v) noexcept |
|
template<typename T > |
void | visit (uint32_t &id, std::string &&typeName, std::string &&name, T &value) noexcept |
|
template<class Visitor > |
void | accept (uint32_t fieldId, Visitor &visitor) |
|
template<class Visitor > |
void | accept (Visitor &visitor) |
|
template<class PreVisitor , class Visitor , class PostVisitor > |
void | accept (PreVisitor &&_preVisit, Visitor &&_visit, PostVisitor &&_postVisit) |
|
GenericMessage is providing an abstraction level to work with concrete messages. Therefore, it is acting as both, a Visitor to turn concrete messages into GenericMessages or as Visitable to access the contained data. GenericMessage would use C++'s std::any type; to allow C++14 compilers, we use the backport from linb::any.
Creating a GenericMessage: There are several ways to create a GenericMessage. The first option is to provide a message specification in ODVD format as result from MessageParser, from which a GenericMessage is created. This instance can then be visited afterwards by, for instance, an instance of ProtoDecoder to set the GenericMessage's actual values.
1) This example demonstrates how to process a given message specification to decode a Proto-encoded byte sequence (in protoEncodedData). The message specification is given in messageSpecification that is parsed from MessageParser. On success, it is tried to decode the Proto-encoded data into a GenericMesssage representing an instance of "MyMessage".
Using a message specification that does not match the serialized Proto data might result in unexpected behavior.
std::string protoEncodedData = <...>
std::stringstream sstr{protoEncodedData};
const char *messageSpecification = R"(
message MyMessage [id = 123] {
int32 field1 [id = 1];
int32 field2 [id = 2];
}
cluon::MessageParser mp;
auto retVal = mp.parse(std::string(messageSpecification));
if (cluon::MessageParser::MessageParserErrorCodes::NO_MESSAGEPARSER_ERROR == retVal.second) {
cluon::GenericMessage gm;
auto listOfMetaMessages = retVal.first;
gm.createFrom(listOfMetaMessages[0], listOfMetaMessages);
// Set values in GenericMessage from protoDecoder.
gm.accept(protoDecoder);
}
2) This example demonstrates how to turn a given concrete message into a GenericMessage. Afterwards, the GenericMessage can be post-processed with Visitors.
After an instance of GenericMessage is available, it can be post-processed into various representations:
1) Printing the contained data ("toString"; GenericMessage is being visited):
std::stringstream buffer;
gm.
accept([](uint32_t,
const std::string &,
const std::string &) {},
[&buffer](uint32_t, std::string &&, std::string &&n, auto v) { buffer << n << " = " << v << std::endl; },
[]() {});
std::cout << buffer.str() << std::endl;
2) Filling the values of another concrete message (GenericMessage is acting as Visitor to another message):
Message msg;
msg.accept(gm);
3) Serialize the GenericMessage gm into a Proto-format:
4) Serialize the GenericMessage gm into JSON:
4) Dynamically transforming a given Proto-encoded byte sequence into JSON at runtime:
std::string protoEncodedData = <...>
std::stringstream sstr{protoEncodedData};
const char *messageSpecification = R"(
message MyMessage [id = 123] {
int32 field1 [id = 1];
int32 field2 [id = 2];
}
cluon::MessageParser mp;
auto retVal = mp.parse(std::string(messageSpecification));
if (cluon::MessageParser::MessageParserErrorCodes::NO_MESSAGEPARSER_ERROR == retVal.second) {
cluon::GenericMessage gm;
auto listOfMetaMessages = retVal.first;
gm.createFrom(listOfMetaMessages[0], listOfMetaMessages);
// Set values in GenericMessage from protoDecoder.
gm.accept(protoDecoder);
}
cluon::ToJSONVisitor j;
gm.accept(j);
std::cout << j.json();