📄 parser.c
字号:
/*********************************************** File: Parser.C* Description:NMEA 解码函数 * Created Date: 2007-10-01* Last Modified: 2007-10-01* Notes: None**********************************************/#include <string.h>#include <stdlib.h>#include "myformat.h"#include "parse.h"#include "parser.h"#include "context.h"typedef struct _nmeaParserNODE{ int packType; void *pack; struct _nmeaParserNODE *next_node;} nmeaParserNODE;/*********************************************** Function: nmea_parser_init(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables:int* Usage:初始化一个NMEA Paerser结构体 **********************************************/int nmea_parser_init(nmeaPARSER *parser){ int resv = 0; int buff_size = nmea_property()->parse_buff_size; NMEA_ASSERT(parser); if(buff_size < NMEA_MIN_PARSEBUFF) buff_size = NMEA_MIN_PARSEBUFF; memset(parser, 0, sizeof(nmeaPARSER)); // 清零 if( (parser->buffer = malloc(buff_size)) == 0) nmea_error("Insufficient memory!"); // 警告内存不足 else { parser->buff_size = buff_size; // 初始化成功 resv = 1; } return resv;}/*********************************************** Function: nmea_parser_destroy(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables:none* Usage:释放一个NMEA Paerser结构体 **********************************************/void nmea_parser_destroy(nmeaPARSER *parser){ NMEA_ASSERT(parser && parser->buffer); free(parser->buffer); // 释放内存 nmea_parser_queue_clear(parser); // 释放队列 memset(parser, 0, sizeof(nmeaPARSER));}/*********************************************** Function: int nmea_parse( nmeaPARSER *parser, const char *buff, int buff_sz, nmeaINFO *info )* Return Variables: int n umber of packets wos parsed* Usage:解析连续的GPS NMEA信息**********************************************/int nmea_parse( nmeaPARSER *parser, const char *buff, int buff_sz, nmeaINFO *info ){ int ptype, nread = 0; void *pack = 0; NMEA_ASSERT(parser && parser->buffer); nmea_parser_push(parser, buff, buff_sz); // 解析NMEA信息 while(GPNON != (ptype = nmea_parser_pop(parser, &pack))) { nread++; switch(ptype) { case GPGGA: // 解析GPGGA nmea_GPGGA2info((nmeaGPGGA *)pack, info); break; case GPGSA: // 解析GPGSA nmea_GPGSA2info((nmeaGPGSA *)pack, info); break; case GPGSV: // 解析GPGSV nmea_GPGSV2info((nmeaGPGSV *)pack, info); break; case GPRMC: // 解析GPRMC nmea_GPRMC2info((nmeaGPRMC *)pack, info); break; case GPVTG: // 解析GPVTG nmea_GPVTG2info((nmeaGPVTG *)pack, info); break; }; free(pack); } return nread; // 返回解析数据包的个数}/*********************************************** nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz)* Input Variables: nmeaPARSER *parser, const char *buff, int buff_sz* Return Variables: int * Usage:在解析链表上增加一个节点**********************************************/int nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz){ int nparsed = 0, crc, sen_sz, ptype; nmeaParserNODE *node = 0;NMEA_ASSERT(parser && parser->buffer); if(parser->buff_use + buff_sz >= parser->buff_size) nmea_parser_buff_clear(parser); memcpy(parser->buffer + parser->buff_use, buff, buff_sz); parser->buff_use += buff_sz; /* parse */ for(;;node = 0) { sen_sz = nmea_find_tail( (const char *)parser->buffer + nparsed, (int)parser->buff_use - nparsed, &crc); // 缓存中是否信息帧是否已经完整 if(!sen_sz) // 信息尚未结束 { if(nparsed) memcpy( parser->buffer, parser->buffer + nparsed, parser->buff_use -= nparsed); break; } else if(crc >= 0) // 增加节点操作 { ptype = nmea_pack_type( (const char *)parser->buffer + nparsed + 1, parser->buff_use - nparsed - 1); if( (node = malloc(sizeof(nmeaParserNODE))) == 0) goto mem_fail; node->pack = 0; switch(ptype) // 判断数据帧类型 { case GPGGA: // GPGGA格式 if( (node->pack = malloc(sizeof(nmeaGPGGA))) ==0) goto mem_fail; node->packType = GPGGA; if(!nmea_parse_GPGGA( (const char *)parser->buffer + nparsed, sen_sz, (nmeaGPGGA *)node->pack)) { free(node); node = 0; } break; case GPGSA: // GPGSA格式 if( (node->pack = malloc(sizeof(nmeaGPGSA)))==0) goto mem_fail; node->packType = GPGSA; if(!nmea_parse_GPGSA( (const char *)parser->buffer + nparsed, sen_sz, (nmeaGPGSA *)node->pack)) { free(node); node = 0; } break; case GPGSV: // GPGSV格式 if( (node->pack = malloc(sizeof(nmeaGPGSV)))==0) goto mem_fail; node->packType = GPGSV; if(!nmea_parse_GPGSV( (const char *)parser->buffer + nparsed, sen_sz, (nmeaGPGSV *)node->pack)) { free(node); node = 0; } break; case GPRMC: // GPRMC格式 if( (node->pack = malloc(sizeof(nmeaGPRMC)))==0) goto mem_fail; node->packType = GPRMC; if(!nmea_parse_GPRMC( (const char *)parser->buffer + nparsed, sen_sz, (nmeaGPRMC *)node->pack)) { free(node); node = 0; } break; case GPVTG: // GPVTG格式 if( (node->pack = malloc(sizeof(nmeaGPVTG)))==0) goto mem_fail; node->packType = GPVTG; if(!nmea_parse_GPVTG( (const char *)parser->buffer + nparsed, sen_sz, (nmeaGPVTG *)node->pack)) { free(node); node = 0; } break; default: free(node); node = 0; break; }; if(node) { if(parser->end_node) ((nmeaParserNODE *)parser->end_node)->next_node = node; parser->end_node = node; if(!parser->top_node) parser->top_node = node; node->next_node = 0; } } nparsed += sen_sz; } return nparsed;mem_fail: if(node) free(node); nmea_error("Insufficient memory!"); // 内存不足 return -1;}/*********************************************** Function:nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz)* Input Variables: nmeaPARSER *parser, const char *buff, int buff_sz* Return Variables: int * Usage:解析缓存区内的NMEA数据信息**********************************************/int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz){ int nparse, nparsed = 0; do // 循环调用nmea_parser_real_push { if(buff_sz > parser->buff_size) nparse = parser->buff_size; else nparse = buff_sz; nparsed += nmea_parser_real_push( parser, buff, nparse); buff_sz -= nparse; } while(buff_sz); // 知道缓存区结束 return nparsed;}/*********************************************** Function: int nmea_parser_top(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables: int * Usage:获得解析链表第一个元素的数据包类型**********************************************/int nmea_parser_top(nmeaPARSER *parser){ int retval = GPNON; nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node; NMEA_ASSERT(parser && parser->buffer); if(node) retval = node->packType; return retval;}/*********************************************** Function: int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr)* Input Variables: nmeaPARSER *parser, void **pack_ptr* Return Variables: int * Usage:从解析链表顶端弹出一个数据包,返回数据为数据包类型**********************************************/int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr){ int retval = GPNON; nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node; NMEA_ASSERT(parser && parser->buffer); if(node) { *pack_ptr = node->pack; retval = node->packType; parser->top_node = node->next_node; if(!parser->top_node) parser->end_node = 0; free(node); } return retval;}/*********************************************** Function: int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr)* Input Variables: nmeaPARSER *parser, void **pack_ptr* Return Variables: int * Usage:从解析链表顶端获得一个数据包,返回数据为数据包类型**********************************************/int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr){ int retval = GPNON; nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node; NMEA_ASSERT(parser && parser->buffer); if(node) { *pack_ptr = node->pack; retval = node->packType; } return retval;}/*********************************************** Function: int nmea_parser_drop(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables: int * Usage:从解析链表顶端释放一个节点**********************************************/int nmea_parser_drop(nmeaPARSER *parser){ int retval = GPNON; nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node; NMEA_ASSERT(parser && parser->buffer); if(node) { if(node->pack) free(node->pack); retval = node->packType; parser->top_node = node->next_node; if(!parser->top_node) parser->end_node = 0; free(node); } return retval;}/*********************************************** Function: int nmea_parser_buff_clear(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables: int * Usage:清除解析链表缓存**********************************************/int nmea_parser_buff_clear(nmeaPARSER *parser){ NMEA_ASSERT(parser && parser->buffer); parser->buff_use = 0; return 1;}/*********************************************** Function: int nmea_parser_queue_clear(nmeaPARSER *parser)* Input Variables: nmeaPARSER *parser* Return Variables: int * Usage:清除解析链表节点**********************************************/int nmea_parser_queue_clear(nmeaPARSER *parser){ NMEA_ASSERT(parser); while(parser->top_node) nmea_parser_drop(parser); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -