diff options
author | iain <iain@linux.intel.com> | 2011-08-16 12:36:59 +0100 |
---|---|---|
committer | iain <iain@linux.intel.com> | 2011-08-16 12:36:59 +0100 |
commit | 6712b13ab09bdd08a79d0adefc4bb61cf64abdd8 (patch) | |
tree | fa17c7ff42e6dcfe9c2aea5930b4dae9590ee0a3 | |
parent | 517cf8448eddf98e0baf0177e8a5e5c7888366ab (diff) |
Remove an additional memcpy when reading from the socket.
Each time we read into a temporary buffer and the memcpy'd the data into the
real buffer. Instead of using the temporary buffer we now ask the parser module
to give us a pointer to the buffer to write to and how much space there is in it
which means we don't need to memcpy.
-rw-r--r-- | src/gypsy-client.c | 11 | ||||
-rw-r--r-- | src/gypsy-garmin-parser.c | 20 | ||||
-rw-r--r-- | src/gypsy-nmea-parser.c | 32 | ||||
-rw-r--r-- | src/gypsy-parser.c | 16 | ||||
-rw-r--r-- | src/gypsy-parser.h | 20 |
5 files changed, 49 insertions, 50 deletions
diff --git a/src/gypsy-client.c b/src/gypsy-client.c index b9c32ea..6b05037 100644 --- a/src/gypsy-client.c +++ b/src/gypsy-client.c @@ -90,7 +90,7 @@ typedef struct _GypsyClientPrivate { GypsyDeviceType type; GIOChannel *channel; /* The channel we talk to the GPS on */ - GIOChannel *debug_log; /* The channel to write the NMEA to, + GIOChannel *debug_log; /* The channel to write the NMEA to, or NULL if debugging is off */ guint32 error_id, connect_id, input_id; @@ -275,15 +275,15 @@ gps_channel_input (GIOChannel *channel, { GypsyClientPrivate *priv; GIOStatus status; - char buf[READ_BUFFER_SIZE]; + char *buf; gsize chars_left_in_buffer, chars_read; GError *error = NULL; priv = GET_PRIVATE (userdata); - chars_left_in_buffer = gypsy_parser_get_space_in_buffer (priv->parser); + chars_left_in_buffer = gypsy_parser_get_buffer (priv->parser, &buf); status = g_io_channel_read_chars (priv->channel, - buf, + (char *) buf, chars_left_in_buffer, &chars_read, NULL); @@ -294,8 +294,7 @@ gps_channel_input (GIOChannel *channel, } if (status == G_IO_STATUS_NORMAL) { - gypsy_parser_received_data (priv->parser, - (guchar *)buf, chars_read, NULL); + gypsy_parser_received_data (priv->parser, chars_read, NULL); } else { g_warning ("Read error: %s", g_strerror (errno)); g_set_error (&error, GYPSY_ERROR, errno, g_strerror (errno)); diff --git a/src/gypsy-garmin-parser.c b/src/gypsy-garmin-parser.c index 9990ff8..5c5fc41 100644 --- a/src/gypsy-garmin-parser.c +++ b/src/gypsy-garmin-parser.c @@ -64,7 +64,7 @@ #define READ_BUFFER_SIZE 1024 struct _GypsyGarminParserPrivate { - guchar sentence[READ_BUFFER_SIZE]; + char buffer[READ_BUFFER_SIZE]; gsize bytes_in_buffer; GDate *epoch; @@ -224,10 +224,9 @@ calculate_speed_course (GypsyGarminParser *parser, } static gboolean -gypsy_garmin_parser_received_data (GypsyParser *parser, - const guchar *data, - gsize length, - GError **error) +gypsy_garmin_parser_received_data (GypsyParser *parser, + gsize length, + GError **error) { GypsyGarminParser *garmin = GYPSY_GARMIN_PARSER (parser); GypsyGarminParserPrivate *priv = garmin->priv; @@ -237,10 +236,9 @@ gypsy_garmin_parser_received_data (GypsyParser *parser, client = gypsy_parser_get_client (parser); - memcpy (priv->sentence + priv->bytes_in_buffer, data, length); priv->bytes_in_buffer += length; - pGpkt = (G_Packet_t*) priv->sentence; + pGpkt = (G_Packet_t*) priv->buffer; pktlen = GARMIN_HEADER_SIZE + pGpkt->mDataSize; while ((priv->bytes_in_buffer >= GARMIN_HEADER_SIZE) && (priv->bytes_in_buffer >= pktlen)) { @@ -316,7 +314,7 @@ gypsy_garmin_parser_received_data (GypsyParser *parser, /* now that we're done with this packet, move any remaining data up to the beginning of the buffer */ - memmove (priv->sentence, priv->sentence + pktlen, + memmove (priv->buffer, priv->buffer + pktlen, priv->bytes_in_buffer - pktlen); priv->bytes_in_buffer -= pktlen; } @@ -325,11 +323,13 @@ gypsy_garmin_parser_received_data (GypsyParser *parser, } static gsize -gypsy_garmin_parser_get_space_in_buffer (GypsyParser *parser) +gypsy_garmin_parser_get_buffer (GypsyParser *parser, + char **buffer) { GypsyGarminParser *garmin = GYPSY_GARMIN_PARSER (parser); GypsyGarminParserPrivate *priv = garmin->priv; + *buffer = (priv->buffer + priv->bytes_in_buffer); return READ_BUFFER_SIZE - priv->bytes_in_buffer; } @@ -343,7 +343,7 @@ gypsy_garmin_parser_class_init (GypsyGarminParserClass *klass) o_class->finalize = gypsy_garmin_parser_finalize; p_class->received_data = gypsy_garmin_parser_received_data; - p_class->get_space_in_buffer = gypsy_garmin_parser_get_space_in_buffer; + p_class->get_buffer = gypsy_garmin_parser_get_buffer; g_type_class_add_private (klass, sizeof (GypsyGarminParserPrivate)); } diff --git a/src/gypsy-nmea-parser.c b/src/gypsy-nmea-parser.c index cab86ce..d8e3195 100644 --- a/src/gypsy-nmea-parser.c +++ b/src/gypsy-nmea-parser.c @@ -34,8 +34,8 @@ struct _GypsyNmeaParserPrivate { NMEAParseContext *ctxt; - char sentence[READ_BUFFER_SIZE + 1]; /* This is for building - the NMEA sentence */ + char buffer[READ_BUFFER_SIZE + 1]; /* This is for building + the NMEA sentence */ gsize chars_in_buffer; /* How many characters are in the buffer */ }; @@ -91,28 +91,26 @@ gypsy_nmea_parser_constructor (GType type, } static gboolean -gypsy_nmea_parser_received_data (GypsyParser *parser, - const guchar *data, - gsize length, - GError **error) +gypsy_nmea_parser_received_data (GypsyParser *parser, + gsize length, + GError **error) { GypsyNmeaParser *nmea = GYPSY_NMEA_PARSER (parser); GypsyNmeaParserPrivate *priv = nmea->priv; char *eos = NULL; - memcpy (priv->sentence + priv->chars_in_buffer, data, length); priv->chars_in_buffer += length; /* Append a '\0' to the data so we never run off the end. The '\0' will be overwritten by the next call to received_data */ - *(priv->sentence + priv->chars_in_buffer) = '\0'; + *(priv->buffer + priv->chars_in_buffer) = '\0'; /* NMEA sentences end with <CR><LF>, so find the <CR> at the end of each sentence */ - while ((eos = strchr (priv->sentence, '\r'))) { + while ((eos = strchr (priv->buffer, '\r'))) { int sentence_length; /* Account for <LF> */ - sentence_length = (eos - priv->sentence) + 2; + sentence_length = (eos - priv->buffer); if (*(eos + 1) == '\n') { sentence_length += 2; @@ -124,16 +122,16 @@ gypsy_nmea_parser_received_data (GypsyParser *parser, /* terminate the string at the <CR> */ *eos = '\0'; - g_debug ("NMEA sentence: %s", priv->sentence); - if (nmea_parse_sentence (priv->ctxt, priv->sentence, NULL) == FALSE) { - g_debug ("Invalid sentence: %s", priv->sentence); + g_debug ("NMEA sentence: %s", priv->buffer); + if (nmea_parse_sentence (priv->ctxt, priv->buffer, NULL) == FALSE) { + g_debug ("Invalid sentence: %s", priv->buffer); } } if (sentence_length > 0) { /* Remove the sentence from the buffer and move the rest up including terminating 0 */ - memmove (priv->sentence, eos + 2, + memmove (priv->buffer, eos + 2, (priv->chars_in_buffer - sentence_length) + 1); priv->chars_in_buffer -= sentence_length; } @@ -143,11 +141,13 @@ gypsy_nmea_parser_received_data (GypsyParser *parser, } static gsize -gypsy_nmea_parser_get_space_in_buffer (GypsyParser *parser) +gypsy_nmea_parser_get_buffer (GypsyParser *parser, + gchar **buffer) { GypsyNmeaParser *nmea = GYPSY_NMEA_PARSER (parser); GypsyNmeaParserPrivate *priv = nmea->priv; + *buffer = (priv->buffer + priv->chars_in_buffer); return READ_BUFFER_SIZE - priv->chars_in_buffer; } @@ -162,7 +162,7 @@ gypsy_nmea_parser_class_init (GypsyNmeaParserClass *klass) o_class->constructor = gypsy_nmea_parser_constructor; p_class->received_data = gypsy_nmea_parser_received_data; - p_class->get_space_in_buffer = gypsy_nmea_parser_get_space_in_buffer; + p_class->get_buffer = gypsy_nmea_parser_get_buffer; g_type_class_add_private (klass, sizeof (GypsyNmeaParserPrivate)); } diff --git a/src/gypsy-parser.c b/src/gypsy-parser.c index 4471191..d086287 100644 --- a/src/gypsy-parser.c +++ b/src/gypsy-parser.c @@ -101,10 +101,9 @@ gypsy_parser_init (GypsyParser *self) } gboolean -gypsy_parser_received_data (GypsyParser *parser, - const guchar *data, - guint length, - GError **error) +gypsy_parser_received_data (GypsyParser *parser, + guint length, + GError **error) { GypsyParserClass *klass = GYPSY_PARSER_GET_CLASS (parser); @@ -114,21 +113,22 @@ gypsy_parser_received_data (GypsyParser *parser, return FALSE; } - return klass->received_data (parser, data, length, error); + return klass->received_data (parser, length, error); } gsize -gypsy_parser_get_space_in_buffer (GypsyParser *parser) +gypsy_parser_get_buffer (GypsyParser *parser, + char **buffer) { GypsyParserClass *klass = GYPSY_PARSER_GET_CLASS (parser); - if (klass->get_space_in_buffer == NULL) { + if (klass->get_buffer == NULL) { g_error ("%s does not implement get_space_in_buffer", G_OBJECT_TYPE_NAME (parser)); return FALSE; } - return klass->get_space_in_buffer (parser); + return klass->get_buffer (parser, buffer); } GypsyClient * diff --git a/src/gypsy-parser.h b/src/gypsy-parser.h index 5b5801c..5005ef1 100644 --- a/src/gypsy-parser.h +++ b/src/gypsy-parser.h @@ -42,19 +42,19 @@ struct _GypsyParserClass { GObjectClass parent_class; - gboolean (*received_data) (GypsyParser *parser, - const guchar *data, - gsize length, - GError **error); - gsize (*get_space_in_buffer) (GypsyParser *parser); + gboolean (*received_data) (GypsyParser *parser, + gsize length, + GError **error); + gsize (*get_buffer) (GypsyParser *parser, + char **buffer); }; GType gypsy_parser_get_type (void) G_GNUC_CONST; -gboolean gypsy_parser_received_data (GypsyParser *parser, - const guchar *data, - guint length, - GError **error); -gsize gypsy_parser_get_space_in_buffer (GypsyParser *parser); +gboolean gypsy_parser_received_data (GypsyParser *parser, + guint length, + GError **error); +gsize gypsy_parser_get_buffer (GypsyParser *parser, + char **buffer); GypsyClient *gypsy_parser_get_client (GypsyParser *parser); G_END_DECLS |