From 0c7fe01a0b85d1645dc0906101c38b4718551b9d Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sun, 29 Nov 2009 06:51:57 +0000 Subject: Enable handling of multiple JSON objectts per line, and add a test for it. --- libgps_core.c | 10 +++++----- libgps_json.c | 24 +++++++++++++++--------- test/clientlib/multipacket.log | 2 ++ test/clientlib/multipacket.log.chk | 4 ++++ test/clientlib/oldstyle.log.chk | 1 + www/protocol-transition.txt | 2 +- 6 files changed, 28 insertions(+), 15 deletions(-) create mode 100644 test/clientlib/multipacket.log create mode 100644 test/clientlib/multipacket.log.chk diff --git a/libgps_core.c b/libgps_core.c index ff8b36f3..ecdf7563 100644 --- a/libgps_core.c +++ b/libgps_core.c @@ -136,20 +136,20 @@ static void libgps_dump_state(struct gps_data_t *collect, time_t now) if (collect->set & STATUS_SET) (void)fprintf(debugfp, "STATUS: status: %d (%s)\n", collect->status, status_values[collect->status]); - if (collect->fix.mode & MODE_SET) + if (collect->set & MODE_SET) (void)fprintf(debugfp, "MODE: mode: %d (%s)\n", - collect->fix.mode, mode_values[collect->fix.mode]); - if (collect->fix.mode & DOP_SET) + collect->set, mode_values[collect->fix.mode]); + if (collect->set & DOP_SET) (void)fprintf(debugfp, "DOP: satellites %d, pdop=%lf, hdop=%lf, vdop=%lf\n", collect->satellites_used, collect->dop.pdop, collect->dop.hdop, collect->dop.vdop); - if (collect->fix.mode & VERSION_SET) + if (collect->set & VERSION_SET) (void)fprintf(debugfp, "VERSION: release=%s rev=%s proto=%d.%d\n", collect->version.release, collect->version.rev, collect->version.proto_major, collect->version.proto_minor); - if (collect->fix.mode & POLICY_SET) + if (collect->set & POLICY_SET) (void)fprintf(debugfp, "POLICY: watcher=%s nmea=%s raw=%d scaled=%s timing=%s, devpath=%s\n", collect->policy.watcher ? "true" : "false", collect->policy.nmea ? "true" : "false", diff --git a/libgps_json.c b/libgps_json.c index 5804ae5c..8c635a67 100644 --- a/libgps_json.c +++ b/libgps_json.c @@ -283,26 +283,31 @@ int libgps_json_unpack(const char *buf, /* the only entry point - unpack a JSON object into gpsdata_t substructures */ { int status; - if (strstr(buf, "\"class\":\"TPV\"") != 0) { + char *classtag = strstr(buf, "\"class\":"); + + if (classtag == NULL) + return -1; +#define STARTSWITH(str, prefix) strncmp(str, prefix, sizeof(prefix)-1)==0 + if (STARTSWITH(classtag, "\"class\":\"TPV\"")) { return json_tpv_read(buf, gpsdata, end); - } else if (strstr(buf, "\"class\":\"SKY\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"SKY\"")) { return json_sky_read(buf, gpsdata, end); - } else if (strstr(buf, "\"class\":\"DEVICES\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"DEVICES\"")) { return json_devicelist_read(buf, gpsdata, end); - } else if (strstr(buf, "\"class\":\"DEVICE\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"DEVICE\"")) { status = json_device_read(buf, &gpsdata->dev, end); if (status == 0) gpsdata->set |= DEVICE_SET; return status; - } else if (strstr(buf, "\"class\":\"WATCH\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"WATCH\"")) { status = json_watch_read(buf, &gpsdata->policy, end); if (status == 0) gpsdata->set |= POLICY_SET; return status; - } else if (strstr(buf, "\"class\":\"VERSION\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"VERSION\"")) { return json_version_read(buf, gpsdata, end); #ifdef RTCM104V2_ENABLE - } else if (strstr(buf, "\"class\":\"RTCM2\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"RTCM2\"")) { status = json_rtcm2_read(buf, gpsdata->dev.path, sizeof(gpsdata->dev.path), &gpsdata->rtcm2, end); @@ -313,7 +318,7 @@ int libgps_json_unpack(const char *buf, return status; #endif /* RTCM104V2_ENABLE */ #ifdef AIVDM_ENABLE - } else if (strstr(buf, "\"class\":\"AIS\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"AIS\"")) { status = json_ais_read(buf, gpsdata->dev.path, sizeof(gpsdata->dev.path), &gpsdata->ais, end); @@ -323,10 +328,11 @@ int libgps_json_unpack(const char *buf, } return status; #endif /* AIVDM_ENABLE */ - } else if (strstr(buf, "\"class\":\"ERROR\"") != 0) { + } else if (STARTSWITH(classtag, "\"class\":\"ERROR\"")) { return json_error_read(buf, gpsdata, end); } else return -1; +#undef STARTSWITH } /*@+compdef@*/ diff --git a/test/clientlib/multipacket.log b/test/clientlib/multipacket.log new file mode 100644 index 00000000..190eee48 --- /dev/null +++ b/test/clientlib/multipacket.log @@ -0,0 +1,2 @@ +# Test the ability to parse multiple packets on the same line +{"class":"VERSION","release":"2.90dev","rev":"svn6614","proto_major":3,"proto_minor":1}{"class":"DEVICES","devices":[{"class":"DEVICE","path":"/dev/ttyS0","activated":1259438908.99,"flags":1,"driver":"SiRF binary","native":1,"bps":4800,"parity":"N","stopbits":1,"cycle":1.00}]}{"class":"WATCH","enable":true,"nmea":false,"raw":0,"scaled":false,"timing":false} diff --git a/test/clientlib/multipacket.log.chk b/test/clientlib/multipacket.log.chk new file mode 100644 index 00000000..a2d2d4e1 --- /dev/null +++ b/test/clientlib/multipacket.log.chk @@ -0,0 +1,4 @@ +flags: (0x808000) {POLICY|DEVICELIST} +POLICY: watcher=true nmea=false raw=0 scaled=false timing=false, devpath= +DEVICELIST:1 devices: +1: path='/dev/ttyS0' driver='SiRF binary' diff --git a/test/clientlib/oldstyle.log.chk b/test/clientlib/oldstyle.log.chk index 60cd0396..69546bd3 100644 --- a/test/clientlib/oldstyle.log.chk +++ b/test/clientlib/oldstyle.log.chk @@ -6,3 +6,4 @@ SPEED: 24.899000 TRACK: track: 70.890000 CLIMB: climb: 0.000000 STATUS: status: 1 (FIX) +MODE: mode: 537598 (MODE_3D) diff --git a/www/protocol-transition.txt b/www/protocol-transition.txt index 8ead0ceb..e38ca805 100644 --- a/www/protocol-transition.txt +++ b/www/protocol-transition.txt @@ -150,7 +150,7 @@ library-internal thread hook. Here's why: are, and our library doesn't. 3. We don't like to ship code we can't test, we didn't have a - regression test for trhe thread stuff, and writing one would + regression test for the thread stuff, and writing one would have been a painful expenditure of time better spent elsewhere. == On not doing things by halves == -- cgit v1.2.1