[MEDIUM] stick-table: make use of generic types for stored data

It's a bit cumbersome to have to know all possible storable types
from the stats interface. Instead, let's have generic types for
all data, which will facilitate their manipulation.
diff --git a/include/proto/stick_table.h b/include/proto/stick_table.h
index 6b80eef..e702356 100644
--- a/include/proto/stick_table.h
+++ b/include/proto/stick_table.h
@@ -50,6 +50,21 @@
 int stktable_get_data_type(char *name);
 struct proxy *find_stktable(const char *name);
 
+/* return allocation size for standard data type <type> */
+static inline int stktable_type_size(int type)
+{
+	switch(type) {
+	case STD_T_SINT:
+	case STD_T_UINT:
+		return sizeof(int);
+	case STD_T_ULL:
+		return sizeof(unsigned long long);
+	case STD_T_FRQP:
+		return sizeof(struct freq_ctr_period);
+	}
+	return 0;
+}
+
 /* reserve some space for data type <type>, and associate argument at <sa> if
  * not NULL. Returns PE_NONE (0) if OK or an error code among :
  *   - PE_ENUM_OOR if <type> does not exist
@@ -85,7 +100,7 @@
 		break;
 	}
 
-	t->data_size      += stktable_data_types[type].data_length;
+	t->data_size      += stktable_type_size(stktable_data_types[type].std_type);
 	t->data_ofs[type]  = -t->data_size;
 	return PE_NONE;
 }
diff --git a/include/types/stick_table.h b/include/types/stick_table.h
index a5f47e3..4338e59 100644
--- a/include/types/stick_table.h
+++ b/include/types/stick_table.h
@@ -60,6 +60,14 @@
 	STKTABLE_DATA_TYPES       /* Number of data types, must always be last */
 };
 
+/* The equivalent standard types of the stored data */
+enum {
+	STD_T_SINT = 0,           /* data is of type signed int */
+	STD_T_UINT,               /* data is of type unsigned int */
+	STD_T_ULL,                /* data is of type unsigned long long */
+	STD_T_FRQP,               /* data is of type freq_ctr_period */
+};
+
 /* The types of optional arguments to stored data */
 enum {
 	ARG_T_NONE = 0,           /* data type takes no argument (default) */
@@ -69,6 +77,13 @@
 
 /* stick_table extra data. This is mainly used for casting or size computation */
 union stktable_data {
+	/* standard types for easy casting */
+	int std_t_sint;
+	unsigned int std_t_uint;
+	unsigned long long std_t_ull;
+	struct freq_ctr_period std_t_frqp;
+
+	/* types of each storable data */
 	int server_id;
 	unsigned int gpc0;
 	unsigned int conn_cnt;
@@ -89,7 +104,7 @@
 /* known data types */
 struct stktable_data_type {
 	const char *name; /* name of the data type */
-	int data_length;  /* length of this type, or 0 if variable (eg: string) */
+	int std_type;     /* standard type we can use for this data, STD_T_* */
 	int arg_type;     /* type of optional argument, ARG_T_* */
 };
 
diff --git a/src/dumpstats.c b/src/dumpstats.c
index 32ca1b9..44bde41 100644
--- a/src/dumpstats.c
+++ b/src/dumpstats.c
@@ -2968,31 +2968,21 @@
 				ptr = stktable_data_ptr(&s->data_ctx.table.proxy->table,
 							s->data_ctx.table.entry,
 							dt);
-				switch (dt) {
-					/* all entries using the same type can be folded */
-				case STKTABLE_DT_SERVER_ID:
-				case STKTABLE_DT_GPC0:
-				case STKTABLE_DT_CONN_CNT:
-				case STKTABLE_DT_CONN_CUR:
-				case STKTABLE_DT_SESS_CNT:
-				case STKTABLE_DT_HTTP_REQ_CNT:
-				case STKTABLE_DT_HTTP_ERR_CNT:
-					chunk_printf(&msg, "%u", stktable_data_cast(ptr, server_id));
+				switch (stktable_data_types[dt].std_type) {
+				case STD_T_SINT:
+					chunk_printf(&msg, "%d", stktable_data_cast(ptr, std_t_sint));
 					break;
-				case STKTABLE_DT_CONN_RATE:
-				case STKTABLE_DT_SESS_RATE:
-				case STKTABLE_DT_HTTP_REQ_RATE:
-				case STKTABLE_DT_HTTP_ERR_RATE:
-				case STKTABLE_DT_BYTES_IN_RATE:
-				case STKTABLE_DT_BYTES_OUT_RATE:
+				case STD_T_UINT:
+					chunk_printf(&msg, "%u", stktable_data_cast(ptr, std_t_uint));
+					break;
+				case STD_T_ULL:
+					chunk_printf(&msg, "%lld", stktable_data_cast(ptr, std_t_ull));
+					break;
+				case STD_T_FRQP:
 					chunk_printf(&msg, "%d",
-						     read_freq_ctr_period(&stktable_data_cast(ptr, conn_rate),
+						     read_freq_ctr_period(&stktable_data_cast(ptr, std_t_frqp),
 									  s->data_ctx.table.proxy->table.data_arg[dt].u));
 					break;
-				case STKTABLE_DT_BYTES_IN_CNT:
-				case STKTABLE_DT_BYTES_OUT_CNT:
-					chunk_printf(&msg, "%lld", stktable_data_cast(ptr, bytes_in_cnt));
-					break;
 				}
 			}
 			chunk_printf(&msg, "\n");
diff --git a/src/stick_table.c b/src/stick_table.c
index 46d5e1e..ccfd7b5 100644
--- a/src/stick_table.c
+++ b/src/stick_table.c
@@ -545,21 +545,21 @@
 
 /* Extra data types processing */
 struct stktable_data_type stktable_data_types[STKTABLE_DATA_TYPES] = {
-	[STKTABLE_DT_SERVER_ID] = { .name = "server_id", .data_length = stktable_data_size(server_id) },
-	[STKTABLE_DT_GPC0]      = { .name = "gpc0",      .data_length = stktable_data_size(gpc0)      },
-	[STKTABLE_DT_CONN_CNT]  = { .name = "conn_cnt",  .data_length = stktable_data_size(conn_cnt)  },
-	[STKTABLE_DT_CONN_RATE] = { .name = "conn_rate", .data_length = stktable_data_size(conn_rate), .arg_type = ARG_T_DELAY  },
-	[STKTABLE_DT_CONN_CUR]  = { .name = "conn_cur",  .data_length = stktable_data_size(conn_cur)  },
-	[STKTABLE_DT_SESS_CNT]  = { .name = "sess_cnt",  .data_length = stktable_data_size(sess_cnt)  },
-	[STKTABLE_DT_SESS_RATE] = { .name = "sess_rate", .data_length = stktable_data_size(sess_rate), .arg_type = ARG_T_DELAY  },
-	[STKTABLE_DT_HTTP_REQ_CNT]  = { .name = "http_req_cnt",  .data_length = stktable_data_size(http_req_cnt)  },
-	[STKTABLE_DT_HTTP_REQ_RATE] = { .name = "http_req_rate", .data_length = stktable_data_size(http_req_rate), .arg_type = ARG_T_DELAY  },
-	[STKTABLE_DT_HTTP_ERR_CNT]  = { .name = "http_err_cnt",  .data_length = stktable_data_size(http_err_cnt)  },
-	[STKTABLE_DT_HTTP_ERR_RATE] = { .name = "http_err_rate", .data_length = stktable_data_size(http_err_rate), .arg_type = ARG_T_DELAY  },
-	[STKTABLE_DT_BYTES_IN_CNT]  = { .name = "bytes_in_cnt",  .data_length = stktable_data_size(bytes_in_cnt)  },
-	[STKTABLE_DT_BYTES_IN_RATE] = { .name = "bytes_in_rate", .data_length = stktable_data_size(bytes_in_rate), .arg_type = ARG_T_DELAY },
-	[STKTABLE_DT_BYTES_OUT_CNT] = { .name = "bytes_out_cnt", .data_length = stktable_data_size(bytes_out_cnt) },
-	[STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate",.data_length = stktable_data_size(bytes_out_rate), .arg_type = ARG_T_DELAY },
+	[STKTABLE_DT_SERVER_ID]     = { .name = "server_id",      .std_type = STD_T_SINT  },
+	[STKTABLE_DT_GPC0]          = { .name = "gpc0",           .std_type = STD_T_UINT  },
+	[STKTABLE_DT_CONN_CNT]      = { .name = "conn_cnt",       .std_type = STD_T_UINT  },
+	[STKTABLE_DT_CONN_RATE]     = { .name = "conn_rate",      .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY  },
+	[STKTABLE_DT_CONN_CUR]      = { .name = "conn_cur",       .std_type = STD_T_UINT  },
+	[STKTABLE_DT_SESS_CNT]      = { .name = "sess_cnt",       .std_type = STD_T_UINT  },
+	[STKTABLE_DT_SESS_RATE]     = { .name = "sess_rate",      .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY  },
+	[STKTABLE_DT_HTTP_REQ_CNT]  = { .name = "http_req_cnt",   .std_type = STD_T_UINT  },
+	[STKTABLE_DT_HTTP_REQ_RATE] = { .name = "http_req_rate",  .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY  },
+	[STKTABLE_DT_HTTP_ERR_CNT]  = { .name = "http_err_cnt",   .std_type = STD_T_UINT  },
+	[STKTABLE_DT_HTTP_ERR_RATE] = { .name = "http_err_rate",  .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY  },
+	[STKTABLE_DT_BYTES_IN_CNT]  = { .name = "bytes_in_cnt",   .std_type = STD_T_ULL   },
+	[STKTABLE_DT_BYTES_IN_RATE] = { .name = "bytes_in_rate",  .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
+	[STKTABLE_DT_BYTES_OUT_CNT] = { .name = "bytes_out_cnt",  .std_type = STD_T_ULL   },
+	[STKTABLE_DT_BYTES_OUT_RATE]= { .name = "bytes_out_rate", .std_type = STD_T_FRQP, .arg_type = ARG_T_DELAY },
 };
 
 /*