nmealib 0.0.4
NMEA 0183/NMEA 2000 parsing library
Loading...
Searching...
No Matches
zda.cpp
Go to the documentation of this file.
2
5
6#include <cmath>
7#include <iomanip>
8#include <sstream>
9#include <vector>
10
11namespace nmealib {
12namespace nmea0183 {
13
14std::unique_ptr<ZDA> ZDA::create(std::unique_ptr<Message0183> baseMessage) {
15 std::string context = "ZDA::create";
16 if (baseMessage->getSentenceType() != "ZDA") {
17 NMEALIB_RETURN_ERROR(NotZDAException(context, "Expected sentence type 'ZDA', got " + baseMessage->getSentenceType()));
18 }
19
20 std::string payload = baseMessage->getPayload();
21 std::istringstream ss(payload);
22 std::string token;
23 std::vector<std::string> fields;
24
25 while (std::getline(ss, token, ',')) {
26 fields.push_back(token);
27 }
28
29 if (!payload.empty() && payload.back() == ',') {
30 fields.push_back("");
31 }
32
33 if (!fields.empty()) {
34 fields.erase(fields.begin());
35 }
36
37 if (fields.size() != 6) {
38 NMEALIB_RETURN_ERROR(NotZDAException(context, "Invalid fields in ZDA payload: expected 6, got " + std::to_string(fields.size()) + ". Payload: " + payload));
39 }
40
41 double utcTime = 0.0;
42 unsigned int day = 0U;
43 unsigned int month = 0U;
44 unsigned int year = 0U;
45 int localZoneHours = 0;
46 int localZoneMinutes = 0;
47 if (!detail::parseOptionalDouble(fields[0], utcTime) ||
48 !detail::parseOptionalUnsigned(fields[1], day) ||
49 !detail::parseOptionalUnsigned(fields[2], month) ||
50 !detail::parseOptionalUnsigned(fields[3], year) ||
51 !detail::parseOptionalInt(fields[4], localZoneHours) ||
52 !detail::parseOptionalInt(fields[5], localZoneMinutes)) {
53 NMEALIB_RETURN_ERROR(NmeaException(context, "Error parsing ZDA fields"));
54 }
55
56 return std::unique_ptr<ZDA>(new ZDA(std::move(*baseMessage),
57 utcTime,
58 day,
59 month,
60 year,
61 localZoneHours,
62 localZoneMinutes));
63}
64
65ZDA::ZDA(Message0183 baseMessage,
66 double utcTime,
67 unsigned int day,
68 unsigned int month,
69 unsigned int year,
70 int localZoneHours,
71 int localZoneMinutes) noexcept
72 : Message0183(std::move(baseMessage)),
73 utcTime_(utcTime),
74 day_(day),
75 month_(month),
76 year_(year),
77 localZoneHours_(localZoneHours),
78 localZoneMinutes_(localZoneMinutes) {}
79
80ZDA::ZDA(std::string talkerId,
81 double utcTime,
82 unsigned int day,
83 unsigned int month,
84 unsigned int year,
85 int localZoneHours,
86 int localZoneMinutes)
87 : Message0183(*Message0183::create(composeRaw(talkerId,
88 utcTime,
89 day,
90 month,
91 year,
92 localZoneHours,
93 localZoneMinutes))),
94 utcTime_(utcTime),
95 day_(day),
96 month_(month),
97 year_(year),
98 localZoneHours_(localZoneHours),
99 localZoneMinutes_(localZoneMinutes) {}
100
101std::unique_ptr<nmealib::Message> ZDA::clone() const {
102 return std::unique_ptr<ZDA>(new ZDA(*this));
103}
104
105std::string ZDA::getStringContent(bool verbose) const noexcept {
106 std::ostringstream ss;
107 ss << this->toString(verbose);
108
109 if (verbose) {
110 ss << "\tUTC Time: " << utcTime_ << "\n";
111 ss << "\tDay: " << day_ << "\n";
112 ss << "\tMonth: " << month_ << "\n";
113 ss << "\tYear: " << year_ << "\n";
114 ss << "\tLocal Zone Hours: " << localZoneHours_ << "\n";
115 ss << "\tLocal Zone Minutes: " << localZoneMinutes_;
116 ss << "\n";
117 } else {
118 ss << "UTC=" << utcTime_
119 << ", Date=" << day_ << "/" << month_ << "/" << year_
120 << ", Zone=" << localZoneHours_ << ":";
121 ss << std::setw(2) << std::setfill('0') << std::abs(localZoneMinutes_);
122 }
123
124 return ss.str();
125}
126
127std::string ZDA::composeRaw(const std::string& talkerId,
128 double utcTime,
129 unsigned int day,
130 unsigned int month,
131 unsigned int year,
132 int localZoneHours,
133 int localZoneMinutes) {
134 std::ostringstream payloadStream;
135 payloadStream << talkerId << "ZDA,";
136 payloadStream << std::fixed << std::setprecision(2) << std::setw(9) << std::setfill('0') << utcTime << ",";
137 payloadStream << std::setw(2) << std::setfill('0') << day << ",";
138 payloadStream << std::setw(2) << std::setfill('0') << month << ",";
139 payloadStream << std::setw(4) << std::setfill('0') << year << ",";
140 payloadStream << localZoneHours << ",";
141 payloadStream << std::setw(2) << std::setfill('0') << std::abs(localZoneMinutes);
142
143 std::string payload = payloadStream.str();
144 return "$" + payload + "\r\n";
145}
146
147double ZDA::getUtcTime() const noexcept {
148 return utcTime_;
149}
150
151unsigned int ZDA::getDay() const noexcept {
152 return day_;
153}
154
155unsigned int ZDA::getMonth() const noexcept {
156 return month_;
157}
158
159unsigned int ZDA::getYear() const noexcept {
160 return year_;
161}
162
163int ZDA::getLocalZoneHours() const noexcept {
164 return localZoneHours_;
165}
166
167int ZDA::getLocalZoneMinutes() const noexcept {
168 return localZoneMinutes_;
169}
170
171bool ZDA::operator==(const ZDA& other) const noexcept {
172 return Message0183::operator==(other);
173}
174
175} // namespace nmea0183
176} // namespace nmealib
Represents an NMEA 0183 sentence.
Definition nmea0183.h:98
bool operator==(const Message0183 &other) const noexcept
Compares two Message0183 objects for equality based on their content and timestamp.
Definition nmea0183.cpp:204
Represents a parsed NMEA 0183 ZDA (Time and Date) sentence.
Definition zda.h:36
std::unique_ptr< nmealib::Message > clone() const override
Create a polymorphic copy of this ZDA message.
Definition zda.cpp:101
unsigned int getYear() const noexcept
Get four-digit year.
Definition zda.cpp:159
int getLocalZoneMinutes() const noexcept
Get local zone offset minutes.
Definition zda.cpp:167
double getUtcTime() const noexcept
Get UTC time in hhmmss.ss numeric form.
Definition zda.cpp:147
bool operator==(const ZDA &other) const noexcept
Compare two ZDA messages for equality.
Definition zda.cpp:171
ZDA(std::string talkerId, double utcTime, unsigned int day, unsigned int month, unsigned int year, int localZoneHours, int localZoneMinutes)
Construct a ZDA message from individual field values.
Definition zda.cpp:80
int getLocalZoneHours() const noexcept
Get local zone offset hours.
Definition zda.cpp:163
unsigned int getMonth() const noexcept
Get month number.
Definition zda.cpp:155
unsigned int getDay() const noexcept
Get day of month.
Definition zda.cpp:151
std::string getStringContent(bool verbose) const noexcept override
Return a human-readable string representation of this message.
Definition zda.cpp:105
#define NMEALIB_RETURN_ERROR(exceptionExpr)
bool parseOptionalInt(const std::string &text, int &value) noexcept
Definition parse.h:110
bool parseOptionalUnsigned(const std::string &text, unsigned int &value) noexcept
Definition parse.h:102
bool parseOptionalDouble(const std::string &text, double &value) noexcept
Definition parse.h:86