summaryrefslogtreecommitdiff
path: root/libgps_core.c
diff options
context:
space:
mode:
authorEric S. Raymond <esr@thyrsus.com>2011-03-18 13:22:31 -0400
committerEric S. Raymond <esr@thyrsus.com>2011-03-18 13:22:31 -0400
commitcd86d4410bcff417de15a0fc5eb905ef56c26596 (patch)
tree54b97075dc41737757b0c5d918c8fc5a0d694614 /libgps_core.c
parentc00be23fbd4cf2aa23d85abc5ec68d31342c010d (diff)
downloadgpsd-cd86d4410bcff417de15a0fc5eb905ef56c26596.tar.gz
In the client API, take the data buffer out of the gpsdata_t structure.
tz has shown me that we had a point of brittleness where the size of the client's data buffer was exposed in gps_data_t. Solution: move it (and the data-waiting count) to the client's private-data member. Requires a new but trivial client-library entry point to get the buffer pointer when a client needs it. Had to be done before API Version 5 froze, or we'd have been stuck breaking a shipped API again. No implications for the daemon or other tools, as this buffer is never used there. (Except it gets rid of several K of never-used static buffer space in the daemon, which is a good thing.) All regression tests pass. Code splints clean. cgps (the only place the API fix matters in our code) live-tests correctly.
Diffstat (limited to 'libgps_core.c')
-rw-r--r--libgps_core.c50
1 files changed, 29 insertions, 21 deletions
diff --git a/libgps_core.c b/libgps_core.c
index d59f3839..23f3e999 100644
--- a/libgps_core.c
+++ b/libgps_core.c
@@ -44,6 +44,10 @@ extern char *strtok_r(char *, const char *, char **);
struct privdata_t
{
bool newstyle;
+ /* data buffered from the last read */
+ ssize_t waiting;
+ char buffer[GPS_JSON_RESPONSE_MAX * 2];
+
};
#define PRIVATE(gpsdata) ((struct privdata_t *)gpsdata->privdata)
@@ -129,9 +133,7 @@ int gps_open(/*@null@*/const char *host, /*@null@*/const char *port,
if (gpsdata->privdata == NULL)
return -1;
PRIVATE(gpsdata)->newstyle = false;
- gpsdata->waiting = 0;
- /*@i1@*/ gpsdata->buffer[0] = '\0';
-
+ PRIVATE(gpsdata)->waiting = 0;
return 0;
/*@ +branchstate @*/
}
@@ -507,7 +509,7 @@ bool gps_waiting(struct gps_data_t * gpsdata, int timeout)
struct timeval tv;
libgps_debug_trace((DEBUG_CALLS, "gps_waiting(%d): %d\n", timeout, waitcount++));
- if (gpsdata->waiting > 0)
+ if (PRIVATE(gpsdata)->waiting > 0)
return true;
/* we might want to check for EINTR if this returns false */
@@ -534,8 +536,8 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
int status = -1;
gpsdata->set &= ~PACKET_SET;
- for (eol = gpsdata->buffer;
- *eol != '\n' && eol < gpsdata->buffer + gpsdata->waiting; eol++)
+ for (eol = PRIVATE(gpsdata)->buffer;
+ *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++)
continue;
if (*eol != '\n')
eol = NULL;
@@ -546,21 +548,21 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
#ifndef USE_QT
/* read data: return -1 if no data waiting or buffered, 0 otherwise */
status = (int)recv(gpsdata->gps_fd,
- gpsdata->buffer + gpsdata->waiting,
- sizeof(gpsdata->buffer) - gpsdata->waiting, 0);
+ PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting,
+ sizeof(PRIVATE(gpsdata)->buffer) - PRIVATE(gpsdata)->waiting, 0);
#else
status =
- ((QTcpSocket *) (gpsdata->gps_fd))->read(gpsdata->buffer +
- gpsdata->waiting,
- sizeof(gpsdata->buffer) -
- gpsdata->waiting);
+ ((QTcpSocket *) (gpsdata->gps_fd))->read(PRIVATE(gpsdata)->buffer +
+ PRIVATE(gpsdata)->waiting,
+ sizeof(PRIVATE(gpsdata)->buffer) -
+ PRIVATE(gpsdata)->waiting);
#endif
/* if we just received data from the socket, it's in the buffer */
if (status > -1)
- gpsdata->waiting += status;
+ PRIVATE(gpsdata)->waiting += status;
/* buffer is empty - implies no data was read */
- if (gpsdata->waiting == 0) {
+ if (PRIVATE(gpsdata)->waiting == 0) {
/*
* If we received 0 bytes, other side of socket is closing.
* Return -1 as end-of-data indication.
@@ -578,8 +580,8 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
return -1;
}
/* there's buffered data waiting to be returned */
- for (eol = gpsdata->buffer;
- *eol != '\n' && eol < gpsdata->buffer + gpsdata->waiting; eol++)
+ for (eol = PRIVATE(gpsdata)->buffer;
+ *eol != '\n' && eol < PRIVATE(gpsdata)->buffer + PRIVATE(gpsdata)->waiting; eol++)
continue;
if (*eol != '\n')
eol = NULL;
@@ -589,20 +591,26 @@ int gps_read(/*@out@*/struct gps_data_t *gpsdata)
assert(eol != NULL);
*eol = '\0';
- response_length = eol - gpsdata->buffer + 1;
+ response_length = eol - PRIVATE(gpsdata)->buffer + 1;
received = gpsdata->online = timestamp();
- status = gps_unpack(gpsdata->buffer, gpsdata);
+ status = gps_unpack(PRIVATE(gpsdata)->buffer, gpsdata);
/*@+matchanyintegral@*/
- memmove(gpsdata->buffer,
- gpsdata->buffer + response_length, gpsdata->waiting - response_length);
+ memmove(PRIVATE(gpsdata)->buffer,
+ PRIVATE(gpsdata)->buffer + response_length, PRIVATE(gpsdata)->waiting - response_length);
/*@-matchanyintegral@*/
- gpsdata->waiting -= response_length;
+ PRIVATE(gpsdata)->waiting -= response_length;
gpsdata->set |= PACKET_SET;
return (status == 0) ? (int)response_length : status;
}
/*@+compdef -usedef +uniondef@*/
+const char /*@observer@*/ *gps_data(struct gps_data_t *gpsdata)
+/* return the contents of the client data buffer */
+{
+ return PRIVATE(gpsdata)->buffer;
+}
+
int gps_send(struct gps_data_t *gpsdata, const char *fmt, ...)
/* send a command to the gpsd instance */
{