23 #include <boost/algorithm/string.hpp> 25 #include "goby/util/binary.h" 27 #include "nmea_sentence.h" 29 bool goby::util::NMEASentence::enforce_talker_length =
true;
31 goby::util::NMEASentence::NMEASentence(std::string s, strategy cs_strat )
33 bool found_csum =
false;
39 throw bad_nmea_sentence(
"NMEASentence: no message provided.");
40 if (s[0] !=
'$' && s[0] !=
'!')
41 throw bad_nmea_sentence(
"NMEASentence: no $ or !: '" + s +
"'.");
45 if (s.size() > 3 && s.at(s.size() - 3) ==
'*')
47 std::string hex_csum = s.substr(s.size() - 2);
48 found_csum = util::hex_string2number(hex_csum, cs);
49 s = s.substr(0, s.size() - 3);
52 if (cs_strat == REQUIRE and !found_csum)
53 throw bad_nmea_sentence(
"NMEASentence: no checksum: '" + s +
"'.");
55 if (found_csum && (cs_strat == REQUIRE || cs_strat == VALIDATE))
57 unsigned char calc_cs = NMEASentence::checksum(s);
59 throw bad_nmea_sentence(
"NMEASentence: bad checksum: '" + s +
"'.");
62 boost::split(*(std::vector<std::string>*)
this, s, boost::is_any_of(
","));
64 if (enforce_talker_length && this->front().size() != 6)
65 throw bad_nmea_sentence(
"NMEASentence: bad talker length '" + s +
"'.");
68 unsigned char goby::util::NMEASentence::checksum(
const std::string& s)
70 unsigned char csum = 0;
73 throw bad_nmea_sentence(
"NMEASentence::checksum: no message provided.");
74 std::string::size_type star = s.find_first_of(
"*");
75 std::string::size_type dollar = s.find_first_of(
"$!");
77 if (dollar == std::string::npos)
78 throw bad_nmea_sentence(
"NMEASentence::checksum: no $ or ! found.");
80 if (star == std::string::npos)
83 for (std::string::size_type i = dollar + 1; i < star; ++i) csum ^= s[i];
87 std::string goby::util::NMEASentence::message_no_cs()
const 89 std::string message =
"";
91 for (const_iterator it = begin(), n = end(); it < n; ++it) message += *it +
",";
94 message.resize(message.size() - 1);
98 std::string goby::util::NMEASentence::message()
const 100 std::string bare = message_no_cs();
101 std::stringstream message;
102 unsigned char csum = NMEASentence::checksum(bare);
103 message << bare <<
"*";
104 message << std::uppercase << std::hex << std::setfill(
'0') << std::setw(2) << unsigned(csum);
105 return message.str();