parser.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. *
  3. * NMEA library
  4. * URL: http://nmea.sourceforge.net
  5. * Author: Tim (xtimor@gmail.com)
  6. * Licence: http://www.gnu.org/licenses/lgpl.html
  7. * $Id: parser.c 17 2008-03-11 11:56:11Z xtimor $
  8. *
  9. */
  10. /**
  11. * \file parser.h
  12. */
  13. #include "nmea/tok.h"
  14. #include "nmea/parse.h"
  15. #include "nmea/parser.h"
  16. #include "nmea/context.h"
  17. #include <string.h>
  18. #include <stdlib.h>
  19. typedef struct _nmeaParserNODE
  20. {
  21. int packType;
  22. void *pack;
  23. struct _nmeaParserNODE *next_node;
  24. } nmeaParserNODE;
  25. /*
  26. * high level
  27. */
  28. /**
  29. * \brief Initialization of parser object
  30. * @return true (1) - success or false (0) - fail
  31. */
  32. int nmea_parser_init(nmeaPARSER *parser)
  33. {
  34. int resv = 0;
  35. int buff_size = nmea_property()->parse_buff_size;
  36. NMEA_ASSERT(parser);
  37. if(buff_size < NMEA_MIN_PARSEBUFF)
  38. buff_size = NMEA_MIN_PARSEBUFF;
  39. memset(parser, 0, sizeof(nmeaPARSER));
  40. if(0 == (parser->buffer = malloc(buff_size)))
  41. nmea_error("Insufficient memory!");
  42. else
  43. {
  44. parser->buff_size = buff_size;
  45. resv = 1;
  46. }
  47. return resv;
  48. }
  49. /**
  50. * \brief Destroy parser object
  51. */
  52. void nmea_parser_destroy(nmeaPARSER *parser)
  53. {
  54. NMEA_ASSERT(parser && parser->buffer);
  55. free(parser->buffer);
  56. nmea_parser_queue_clear(parser);
  57. memset(parser, 0, sizeof(nmeaPARSER));
  58. }
  59. /**
  60. * \brief Analysis of buffer and put results to information structure
  61. * @return Number of packets wos parsed
  62. */
  63. int nmea_parse(
  64. nmeaPARSER *parser,
  65. const char *buff, int buff_sz,
  66. nmeaINFO *info
  67. )
  68. {
  69. int ptype, nread = 0;
  70. void *pack = 0;
  71. NMEA_ASSERT(parser && parser->buffer);
  72. nmea_parser_push(parser, buff, buff_sz);
  73. while(GPNON != (ptype = nmea_parser_pop(parser, &pack)))
  74. {
  75. nread++;
  76. switch(ptype)
  77. {
  78. case GPGGA:
  79. nmea_GPGGA2info((nmeaGPGGA *)pack, info);
  80. break;
  81. case GPGSA:
  82. nmea_GPGSA2info((nmeaGPGSA *)pack, info);
  83. break;
  84. case GPGSV:
  85. nmea_GPGSV2info((nmeaGPGSV *)pack, info);
  86. break;
  87. case GPRMC:
  88. nmea_GPRMC2info((nmeaGPRMC *)pack, info);
  89. break;
  90. case GNRMC:
  91. nmea_GNRMC2info((nmeaGPRMC *)pack, info);
  92. break;
  93. case GPVTG:
  94. nmea_GPVTG2info((nmeaGPVTG *)pack, info);
  95. break;
  96. case GNGGA:
  97. //printf("nmea解析GNGGA成功:%s\n",info);
  98. nmea_GNGGA2info((nmeaGPGGA *)pack, info);
  99. break;
  100. case BDGSV:
  101. //printf("nmea解析BDGSV成功:%s\n",info);
  102. nmea_BDGSV2info((nmeaGPGSV *)pack, info);
  103. break;
  104. case GNGSA:
  105. nmea_GNGSA2info((nmeaGPGSA *)pack, info);
  106. break;
  107. };
  108. free(pack);
  109. }
  110. return nread;
  111. }
  112. /*
  113. * low level
  114. */
  115. int nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz)
  116. {
  117. int nparsed = 0, crc, sen_sz, ptype;
  118. nmeaParserNODE *node = 0;
  119. NMEA_ASSERT(parser && parser->buffer);
  120. /* clear unuse buffer (for debug) */
  121. /*
  122. memset(
  123. parser->buffer + parser->buff_use, 0,
  124. parser->buff_size - parser->buff_use
  125. );
  126. */
  127. /* add */
  128. if(parser->buff_use + buff_sz >= parser->buff_size)
  129. nmea_parser_buff_clear(parser);
  130. memcpy(parser->buffer + parser->buff_use, buff, buff_sz);
  131. parser->buff_use += buff_sz;
  132. /* parse */
  133. for(;;node = 0)
  134. {
  135. sen_sz = nmea_find_tail(
  136. (const char *)parser->buffer + nparsed,
  137. (int)parser->buff_use - nparsed, &crc);
  138. if(!sen_sz)
  139. {
  140. if(nparsed)
  141. memcpy(
  142. parser->buffer,
  143. parser->buffer + nparsed,
  144. parser->buff_use -= nparsed);
  145. break;
  146. }
  147. else if(crc >= 0)
  148. {
  149. ptype = nmea_pack_type(
  150. (const char *)parser->buffer + nparsed + 1,
  151. parser->buff_use - nparsed - 1);
  152. //printf("\n解析到nmea_parser_real_push:%d\n",ptype);
  153. if(0 == (node = malloc(sizeof(nmeaParserNODE))))
  154. goto mem_fail;
  155. node->pack = 0;
  156. switch(ptype)
  157. {
  158. case GPGGA:
  159. if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
  160. goto mem_fail;
  161. node->packType = GPGGA;
  162. if(!nmea_parse_GPGGA(
  163. (const char *)parser->buffer + nparsed,
  164. sen_sz, (nmeaGPGGA *)node->pack))
  165. {
  166. free(node);
  167. node = 0;
  168. }
  169. break;
  170. case GNGGA:
  171. if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
  172. goto mem_fail;
  173. node->packType = GPGGA;
  174. if(!nmea_parse_GNGGA(
  175. (const char *)parser->buffer + nparsed,
  176. sen_sz, (nmeaGPGGA *)node->pack))
  177. {
  178. free(node);
  179. node = 0;
  180. }
  181. break;
  182. case GPGSA:
  183. if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
  184. goto mem_fail;
  185. node->packType = GPGSA;
  186. if(!nmea_parse_GPGSA(
  187. (const char *)parser->buffer + nparsed,
  188. sen_sz, (nmeaGPGSA *)node->pack))
  189. {
  190. free(node);
  191. node = 0;
  192. }
  193. break;
  194. case GNGSA:
  195. if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
  196. goto mem_fail;
  197. node->packType = GPGSA;
  198. if(!nmea_parse_GNGSA(
  199. (const char *)parser->buffer + nparsed,
  200. sen_sz, (nmeaGPGSA *)node->pack))
  201. {
  202. free(node);
  203. node = 0;
  204. }
  205. break;
  206. case GPGSV:
  207. if(0 == (node->pack = malloc(sizeof(nmeaGPGSV))))
  208. goto mem_fail;
  209. node->packType = GPGSV;
  210. if(!nmea_parse_GPGSV(
  211. (const char *)parser->buffer + nparsed,
  212. sen_sz, (nmeaGPGSV *)node->pack))
  213. {
  214. free(node);
  215. node = 0;
  216. }
  217. break;
  218. case BDGSV:
  219. if(0 == (node->pack = malloc(sizeof(nmeaGPGSV))))
  220. goto mem_fail;
  221. node->packType = BDGSV;
  222. if(!nmea_parse_BDGSV(
  223. (const char *)parser->buffer + nparsed,
  224. sen_sz, (nmeaGPGSV *)node->pack))
  225. {
  226. free(node);
  227. node = 0;
  228. }
  229. break;
  230. case GPRMC:
  231. if(0 == (node->pack = malloc(sizeof(nmeaGPRMC))))
  232. goto mem_fail;
  233. node->packType = GPRMC;
  234. if(!nmea_parse_GPRMC(
  235. (const char *)parser->buffer + nparsed,
  236. sen_sz, (nmeaGPRMC *)node->pack))
  237. {
  238. free(node);
  239. node = 0;
  240. }
  241. break;
  242. case GNRMC:
  243. if(0 == (node->pack = malloc(sizeof(nmeaGPRMC))))
  244. goto mem_fail;
  245. node->packType = GPRMC;
  246. if(!nmea_parse_GNRMC(
  247. (const char *)parser->buffer + nparsed,
  248. sen_sz, (nmeaGPRMC *)node->pack))
  249. {
  250. free(node);
  251. node = 0;
  252. }
  253. break;
  254. case GPVTG:
  255. if(0 == (node->pack = malloc(sizeof(nmeaGPVTG))))
  256. goto mem_fail;
  257. node->packType = GPVTG;
  258. if(!nmea_parse_GPVTG(
  259. (const char *)parser->buffer + nparsed,
  260. sen_sz, (nmeaGPVTG *)node->pack))
  261. {
  262. free(node);
  263. node = 0;
  264. }
  265. break;
  266. default:
  267. free(node);
  268. node = 0;
  269. break;
  270. };
  271. if(node)
  272. {
  273. if(parser->end_node)
  274. ((nmeaParserNODE *)parser->end_node)->next_node = node;
  275. parser->end_node = node;
  276. if(!parser->top_node)
  277. parser->top_node = node;
  278. node->next_node = 0;
  279. }
  280. }
  281. nparsed += sen_sz;
  282. }
  283. return nparsed;
  284. mem_fail:
  285. if(node)
  286. free(node);
  287. nmea_error("Insufficient memory!");
  288. return -1;
  289. }
  290. /**
  291. * \brief Analysis of buffer and keep results into parser
  292. * @return Number of bytes wos parsed from buffer
  293. */
  294. int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz)
  295. {
  296. int nparse, nparsed = 0;
  297. do
  298. {
  299. if(buff_sz > parser->buff_size)
  300. nparse = parser->buff_size;
  301. else
  302. nparse = buff_sz;
  303. nparsed += nmea_parser_real_push(
  304. parser, buff, nparse);
  305. buff_sz -= nparse;
  306. } while(buff_sz);
  307. return nparsed;
  308. }
  309. /**
  310. * \brief Get type of top packet keeped into parser
  311. * @return Type of packet
  312. * @see nmeaPACKTYPE
  313. */
  314. int nmea_parser_top(nmeaPARSER *parser)
  315. {
  316. int retval = GPNON;
  317. nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
  318. NMEA_ASSERT(parser && parser->buffer);
  319. if(node)
  320. retval = node->packType;
  321. return retval;
  322. }
  323. /**
  324. * \brief Withdraw top packet from parser
  325. * @return Received packet type
  326. * @see nmeaPACKTYPE
  327. */
  328. int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr)
  329. {
  330. int retval = GPNON;
  331. nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
  332. NMEA_ASSERT(parser && parser->buffer);
  333. if(node)
  334. {
  335. *pack_ptr = node->pack;
  336. retval = node->packType;
  337. parser->top_node = node->next_node;
  338. if(!parser->top_node)
  339. parser->end_node = 0;
  340. free(node);
  341. }
  342. return retval;
  343. }
  344. /**
  345. * \brief Get top packet from parser without withdraw
  346. * @return Received packet type
  347. * @see nmeaPACKTYPE
  348. */
  349. int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr)
  350. {
  351. int retval = GPNON;
  352. nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
  353. NMEA_ASSERT(parser && parser->buffer);
  354. if(node)
  355. {
  356. *pack_ptr = node->pack;
  357. retval = node->packType;
  358. }
  359. return retval;
  360. }
  361. /**
  362. * \brief Delete top packet from parser
  363. * @return Deleted packet type
  364. * @see nmeaPACKTYPE
  365. */
  366. int nmea_parser_drop(nmeaPARSER *parser)
  367. {
  368. int retval = GPNON;
  369. nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
  370. NMEA_ASSERT(parser && parser->buffer);
  371. if(node)
  372. {
  373. if(node->pack)
  374. free(node->pack);
  375. retval = node->packType;
  376. parser->top_node = node->next_node;
  377. if(!parser->top_node)
  378. parser->end_node = 0;
  379. free(node);
  380. }
  381. return retval;
  382. }
  383. /**
  384. * \brief Clear cache of parser
  385. * @return true (1) - success
  386. */
  387. int nmea_parser_buff_clear(nmeaPARSER *parser)
  388. {
  389. NMEA_ASSERT(parser && parser->buffer);
  390. parser->buff_use = 0;
  391. return 1;
  392. }
  393. /**
  394. * \brief Clear packets queue into parser
  395. * @return true (1) - success
  396. */
  397. int nmea_parser_queue_clear(nmeaPARSER *parser)
  398. {
  399. NMEA_ASSERT(parser);
  400. while(parser->top_node)
  401. nmea_parser_drop(parser);
  402. return 1;
  403. }