stats: Use function pointers in reporter objects

Currently case statements are used to select the right reporter
functions. This makes it difficult to add new reporter types,
especially if they are not going to reside in the same file.

This commit introduces per reporter function pointer for
open, close, send_count, and send_item. They are checked for
non-NULL before being called or skipped.

Sponsored-by: On-Waves ehf
diff --git a/src/stats.c b/src/stats.c
index 6189cb3..f4c0b62 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -60,6 +60,14 @@
 
 static int stats_reporter_statsd_open(struct stats_reporter *srep);
 static int stats_reporter_statsd_close(struct stats_reporter *srep);
+static int stats_reporter_statsd_send_counter(struct stats_reporter *srep,
+	const struct rate_ctr_group *ctrg,
+	const struct rate_ctr_desc *desc,
+	int64_t value, int64_t delta);
+static int stats_reporter_statsd_send_item(struct stats_reporter *srep,
+	const struct stat_item_group *statg,
+	const struct stat_item_desc *desc, int value);
+
 static int stats_reporter_send(struct stats_reporter *srep, const char *data,
 	int data_len);
 static int stats_reporter_send_buffer(struct stats_reporter *srep);
@@ -68,20 +76,20 @@
 {
 	int rc = 0;
 
-	if (srep->type != STATS_REPORTER_STATSD) {
-		srep->enabled = 0;
-		return -ENOTSUP;
-	}
-
 	if (srep->running) {
-		rc = stats_reporter_statsd_close(srep);
+		if (srep->close)
+			rc = srep->close(srep);
 		srep->running = 0;
 	}
 
 	if (!srep->enabled)
 		return rc;
 
-	rc = stats_reporter_statsd_open(srep);
+	if (srep->open)
+		rc = srep->open(srep);
+	else
+		rc = 0;
+
 	if (rc < 0)
 		srep->enabled = 0;
 	else
@@ -310,6 +318,11 @@
 
 	srep->have_net_config = 1;
 
+	srep->open = stats_reporter_statsd_open;
+	srep->close = stats_reporter_statsd_close;
+	srep->send_counter = stats_reporter_statsd_send_counter;
+	srep->send_item = stats_reporter_statsd_send_item;
+
 	return srep;
 }
 
@@ -461,16 +474,10 @@
 	const struct rate_ctr_desc *desc,
 	int64_t value, int64_t delta)
 {
-	int rc;
+	if (!srep->send_counter)
+		return 0;
 
-	switch (srep->type) {
-	case STATS_REPORTER_STATSD:
-		rc = stats_reporter_statsd_send_counter(srep, ctrg, desc,
-			value, delta);
-		break;
-	}
-
-	return rc;
+	return srep->send_counter(srep, ctrg, desc, value, delta);
 }
 
 static int rate_ctr_handler(
@@ -511,16 +518,10 @@
 	const struct stat_item_desc *desc,
 	int32_t value)
 {
-	int rc;
+	if (!srep->send_item)
+		return 0;
 
-	switch (srep->type) {
-	case STATS_REPORTER_STATSD:
-		rc = stats_reporter_statsd_send_item(srep, statg, desc,
-			value);
-		break;
-	}
-
-	return rc;
+	return srep->send_item(srep, statg, desc, value);
 }
 
 static int stat_item_handler(