From 319ee643ad919b43f65eca4d98dfb3e12c89214a Mon Sep 17 00:00:00 2001 From: Steffen Vogel Date: Mon, 12 Mar 2012 01:32:54 +0100 Subject: [PATCH] added registry to manage memory for string identifiers --- include/reading.h | 8 ++++++++ src/reading.c | 29 +++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/include/reading.h b/include/reading.h index 500e0ad..9f8ee98 100644 --- a/include/reading.h +++ b/include/reading.h @@ -51,6 +51,14 @@ typedef struct reading { enum meter_procotol; /* forward declaration */ +/** + * Manages memory for string identifiers + * + * @param str string to lookup in the registry + * @return pointer to string in the regstry + */ +char * reading_id_registry(const char *str); + /** * Parse two reading identifiers in a given protocol context * diff --git a/src/reading.c b/src/reading.c index cb01c46..a4dcfcb 100644 --- a/src/reading.c +++ b/src/reading.c @@ -25,10 +25,32 @@ #include #include +#include #include "reading.h" #include "meter.h" +char * reading_id_registry(const char *str) { + static list_t strings; + + char *found = NULL; + + /* linear search in string list */ + foreach(strings, it, char *) { + if (strcmp(it, str) == 0) { + found = it; + break; + } + } + + if (!found) { + found = strdup(str); + list_push(strings, found); + } + + return found; +} + int reading_id_compare(meter_protocol_t protocol, reading_id_t a, reading_id_t b) { switch (protocol) { case meter_protocol_d0: @@ -40,7 +62,10 @@ int reading_id_compare(meter_protocol_t protocol, reading_id_t a, reading_id_t b case meter_protocol_file: case meter_protocol_exec: - return strcmp(a.string, b.string); + /* we only need to compare the base pointers here, + because each identifer exists only once in the registry + and has therefore a unique pointer */ + return !(a.string == b.string); default: /* no channel id, adding all readings to buffer */ @@ -81,7 +106,7 @@ int reading_id_parse(meter_protocol_t protocol, reading_id_t *id, const char *st case meter_protocol_file: case meter_protocol_exec: - id->string = strdup(string); // TODO free() elsewhere + id->string = reading_id_registry(string); break; default: /* ignore other protocols which do not provide id's */