13std::unique_ptr<XDR> XDR::create(std::unique_ptr<Message0183> baseMessage) {
14 std::string context =
"XDR::create";
15 if (baseMessage->getSentenceType() !=
"XDR") {
16 NMEALIB_RETURN_ERROR(NotXDRException(context,
"Expected sentence type 'XDR', got " + baseMessage->getSentenceType()));
19 std::string payload = baseMessage->getPayload();
20 std::istringstream ss(payload);
22 std::vector<std::string> fields;
24 while (std::getline(ss, token,
',')) {
25 fields.push_back(token);
28 if (!payload.empty() && payload.back() ==
',') {
32 if (!fields.empty()) {
33 fields.erase(fields.begin());
36 if (fields.empty() || (fields.size() % 4) != 0) {
37 NMEALIB_RETURN_ERROR(NotXDRException(context,
"Invalid fields in XDR payload: expected one or more quadruplets, got " + std::to_string(fields.size()) +
" fields. Payload: " + payload));
40 std::vector<TransducerMeasurement> transducers;
41 transducers.reserve(fields.size() / 4);
43 for (std::size_t index = 0; index < fields.size(); index += 4) {
44 TransducerMeasurement measurement;
45 measurement.transducerType = fields[index].empty() ?
'\0' : fields[index][0];
49 measurement.units = fields[index + 2].empty() ?
'\0' : fields[index + 2][0];
50 measurement.name = fields[index + 3];
51 transducers.push_back(std::move(measurement));
54 return std::unique_ptr<XDR>(
new XDR(std::move(*baseMessage), std::move(transducers)));
57XDR::XDR(Message0183 baseMessage, std::vector<TransducerMeasurement> transducers) noexcept
58 : Message0183(std::move(baseMessage)),
59 transducers_(std::move(transducers)) {}
61XDR::XDR(std::string talkerId, std::vector<TransducerMeasurement> transducers)
63 transducers_(std::move(transducers)) {}
66 return std::unique_ptr<XDR>(
new XDR(*
this));
70 std::ostringstream ss;
71 ss << this->toString(verbose);
74 ss <<
"\tTransducers: " << transducers_.size() <<
"\n";
75 for (std::size_t index = 0; index < transducers_.size(); ++index) {
76 const auto& transducer = transducers_[index];
77 ss <<
"\t[" << index <<
"] Type=" << transducer.transducerType
78 <<
", Value=" << transducer.measurement
79 <<
", Units=" << transducer.units
80 <<
", Name=" << transducer.name <<
"\n";
83 ss <<
"Transducers=" << transducers_.size();
89std::string XDR::composeRaw(
const std::string& talkerId,
90 const std::vector<TransducerMeasurement>& transducers) {
91 std::ostringstream payloadStream;
92 payloadStream << talkerId <<
"XDR";
94 payloadStream << std::setprecision(15);
95 for (
const auto& transducer : transducers) {
97 if (transducer.transducerType !=
'\0') {
98 payloadStream << transducer.transducerType;
100 payloadStream <<
",";
101 payloadStream << transducer.measurement;
102 payloadStream <<
",";
103 if (transducer.units !=
'\0') {
104 payloadStream << transducer.units;
106 payloadStream <<
",";
107 payloadStream << transducer.name;
110 std::string payload = payloadStream.str();
111 return "$" + payload +
"\r\n";
119 return transducers_.size();
123 if (index >= transducers_.size()) {
126 return &transducers_[index];
Represents an NMEA 0183 sentence.
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
Represents a parsed NMEA 0183 XDR (Transducer Measurement) sentence.
std::size_t getTransducerCount() const noexcept
Get the number of transducer measurements in this sentence.
bool operator==(const XDR &other) const noexcept
Compare two XDR messages for equality.
const std::vector< TransducerMeasurement > & getTransducers() const noexcept
Get all transducer measurements in this sentence.
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this XDR message.
XDR(std::string talkerId, std::vector< TransducerMeasurement > transducers)
Construct an XDR message from field values.
const TransducerMeasurement * getTransducer(std::size_t index) const noexcept
Get a transducer measurement by index.
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseOptionalDouble(const std::string &text, double &value) noexcept
One transducer measurement quadruplet in an XDR sentence.