NEMA数据解析C++

#ifndef NEMAPARSE_HPP
#define NEMAPARSE_HPP

#include <string>
#include <string.h>
#include <vector>
#include <functional>

#include "simplelog.h"

#define NEMAHEADLEN 3

class nemaparse{
public:
    nemaparse(){
        nemaheaders.push_back("GGA");
        nemaheaders.push_back("RMC");
        nemaheaders.push_back("GST");

        nemahandler = 0;
    }
public:
    bool onNemaMessage(uint8_t* x, int n){
        try {
            if (nemahandler != nullptr){
                //
                std::string hd = std::string((const char*)x + 3, 3);
                std::string xlog = std::string((const char*)x, n + 2);
                nemahandler(hd, xlog);
            }
            //LOGFORMAT_I("%s\n", std::string((const char*)x, n + 2).c_str());
            return true;
        }catch(std::exception& exc){

        }
        return false;
    }
    void parseNema(uint8_t *x, int n){
        try {
            if (x == nullptr || n < 1)
                return;

            static int buffer_len = 1024 * 1024;
            static uint8_t* parse_buffer = new uint8_t[buffer_len]{};

            static int start_index = 0;
            static int end_index = 0;

            static std::vector<std::string>::iterator _hditer;

            //当前缓存的空间不足以存放新消息了
            if ((n + end_index) >= buffer_len){
                //exception出现这种问题是由于下面那个for循环的逻辑出现问题,一般不会出现end 小于 start的情况
                if (end_index < start_index)
                {
                    //error
                    LOGFORMAT_I("(end_index < start_index) start:%d end:%d", start_index, end_index);
                    end_index = start_index = 0;
                }
                else {
                    //把老数据拷贝到缓存开头位置,类似于缓存重置,但是保留了老数据
                    memmove(parse_buffer, parse_buffer + start_index, end_index - start_index);
                    end_index = end_index - start_index;
                    start_index = 0;
                }
            }
            //缓存的老数据过多,或者是新来的数据太多,导致缓存爆炸
            if ((n + end_index) >= buffer_len){
                LOGFORMAT_I("buffer is wrong, too much data in cache(n:%d start_index:%d end_index:%d)", n, start_index, end_index);
                end_index = start_index = 0;
            }
            //put data in parse_buffer
            //新来的数据
            memmove(parse_buffer + end_index, x, n);
            end_index = end_index + n;

            //是否找到消息头,每找到一次完整消息,需要将它重置为false,便于下一次寻找
            bool matchmsg = false;

            ///
            //当前消息的开始下标'$', 当前消息的终止下标'*',因为出现过缺少\r\n的先例
            int msg_start = -1, msg_end = -1;
            for (int i = start_index; i < end_index - 7; ++ i){
                //找消息头
                //match the head '$'
                if (parse_buffer[i] == '$'){
                    for (_hditer = nemaheaders.begin(); _hditer != nemaheaders.end(); ++ _hditer) {
                        //match the log
                        if (memcmp(_hditer->c_str(), parse_buffer + i + 3, NEMAHEADLEN) == 0){
                            msg_start = i;
                            matchmsg = true;
                            break;
                        }
                    }

                    if (matchmsg)
                        continue;
                }
                //找到消息头后再找消息尾
                if (matchmsg){
                    if(parse_buffer[i] == '*'){
                        //match the end '*'
                        msg_end = i + 1;

                        //回调出去
                        onNemaMessage(parse_buffer + msg_start, msg_end - msg_start);

                        //std::string msg = std::string((const char*)parse_buffer + msg_start, msg_end - msg_start);
                        //LOGFORMAT_I("I FOUND SYNC MSG: %s", msg.c_str());

                        //new match loop
                        matchmsg = false;
                        start_index = i;
                    }
                }
            }
            ///
            return;
        }catch(std::exception& exc){
            //
        }
        return;
    }
    void sethandler(std::function<void(std::string& hd, std::string& xlog)> func){
        nemahandler = func;
    }
public:
    std::function<void(std::string& hd, std::string& xlog)> nemahandler;
    std::vector<std::string> nemaheaders;
};
#endif // NEMAPARSE_HPP

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值