我在写一个NMEAParser库。 顾名思义,它解析NMEA句子。 没什么疯狂的。
它的入口点是一个函数,它接受一个NMEA字符串作为它的唯一参数,并查看它的开头将它传递给正确的解码器。 下面是功能:
bool NMEAParser::dispatch(const char *str) {
if (!str[0]) {
return false;
}
//check NMEA string type
if (str[0] == '$') {
//PLSR245X
if (str[1] == 'P' && str[2] == 'L' && str[3] == 'S' && str[4] == 'R' && str[5] == ',' && str[6] == '2' && str[7] == '4' && str[8] == '5' && str[9] == ',') {
if (str[10] == '1')
return parsePLSR2451(str);
if (str[10] == '2')
return parsePLSR2452(str);
if (str[10] == '7')
return parsePLSR2457(str);
} else if (str[1] == 'G' && str[2] == 'P') {
//GPGGA
if (str[3] == 'G' && str[4] == 'G' && str[5] == 'A')
return parseGPGGA(str);
//GPGSA
else if (str[3] == 'G' && str[4] == 'S' && str[5] == 'A')
return parseGPGSA(str);
//GPGSV
else if (str[3] == 'G' && str[4] == 'S' && str[5] == 'V')
return parseGPGSV(str);
//GPRMC
else if (str[3] == 'R' && str[4] == 'M' && str[5] == 'C')
return parseGPRMC(str);
//GPVTG
else if (str[3] == 'V' && str[4] == 'T' && str[5] == 'G')
return parseGPVTG(str);
//GPTXT
else if (str[3] == 'T' && str[4] == 'X' && str[5] == 'T')
return parseGPTXT(str);
//GPGLL
else if (str[3] == 'G' && str[4] == 'L' && str[5] == 'L')
return parseGPGLL(str);
}
//HCHDG
else if (str[1] == 'H' && str[2] == 'C' && str[3] == 'H' && str[4] == 'D' && str[5] == 'G')
return parseHCHDG(str);
}
return false;
}
这不是真正的问题,因为代码非常容易阅读。 但我想知道如何降低它的复杂性,同时保持它的简单易读和高效。
您可以将其简化很多:
if (std::string_view{str, 10} == "$PLSR,245,")
{
switch (str[10])
{
case '1' : return parsePLSR2451(str);
case '2' : return parsePLSR2452(str);
case '7' : return parsePLSR2457(str);
}
}
else if (std::string_view{str + 1, 2} == "GP")
{
auto s = std::string_view{str + 3, 3};
if (s == "GGA")
return parseGPGGA(str);
if (s == "GSA")
return parseGPGSA(str);
// ... etc
}
else if (std::string_view{str + 1, 5} == "HCHDG")
{
return parseHCHDG(str);
}
return false;
也没有构造额外的string
,因此它至少应该同样有效。