2 * UCW Library -- Table printer types
4 * (c) 2014 Robert Kessl <robert.kessl@economia.cz>
8 #include <ucw/table-types.h>
9 #include <ucw/fastbuf.h>
10 #include <ucw/table.h>
18 static const char *unit_suffix[] = {
19 [SIZE_UNIT_BYTE] = "",
20 [SIZE_UNIT_KILOBYTE] = "KB",
21 [SIZE_UNIT_MEGABYTE] = "MB",
22 [SIZE_UNIT_GIGABYTE] = "GB",
23 [SIZE_UNIT_TERABYTE] = "TB"
26 static const char *xt_size_format(void *src, u32 fmt, struct mempool *pool)
28 u64 curr_val = *(u64*) src;
30 if(fmt == XTYPE_FMT_RAW) {
31 return mp_printf(pool, "%"PRIu64, curr_val);
34 uint out_type = SIZE_UNIT_BYTE;
36 static u64 unit_div[] = {
37 [SIZE_UNIT_BYTE] = 1LLU,
38 [SIZE_UNIT_KILOBYTE] = 1024LLU,
39 [SIZE_UNIT_MEGABYTE] = 1024LLU * 1024LLU,
40 [SIZE_UNIT_GIGABYTE] = 1024LLU * 1024LLU * 1024LLU,
41 [SIZE_UNIT_TERABYTE] = 1024LLU * 1024LLU * 1024LLU * 1024LLU
44 if(fmt == XTYPE_FMT_DEFAULT) {
45 curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
46 out_type = SIZE_UNIT_BYTE;
47 } else if(fmt == XTYPE_FMT_PRETTY) {
48 curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
49 out_type = SIZE_UNIT_BYTE;
50 } else if((fmt & SIZE_UNITS_FIXED) != 0) {
51 curr_val = curr_val / unit_div[fmt & ~SIZE_UNITS_FIXED];
52 out_type = fmt & ~SIZE_UNITS_FIXED;
55 return mp_printf(pool, "%"PRIu64"%s", curr_val, unit_suffix[out_type]);
58 int table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
61 *err = "NULL is not supported as a column argument.";
65 const struct table_column *col_def = tbl->column_order[col_inst_idx].col_def;
66 if(col_def->type_def != &xt_size) {
68 return TABLE_OPT_UNKNOWN;
71 if(strlen(col_arg) == 0 || strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
72 tbl->column_order[col_inst_idx].output_type = SIZE_UNIT_BYTE | SIZE_UNITS_FIXED;
74 return TABLE_OPT_PROCESSED;
77 tbl->column_order[col_inst_idx].output_type = XTYPE_FMT_DEFAULT; // CELL_OUT_UNINITIALIZED;
78 for(uint i = SIZE_UNIT_BYTE; i <= SIZE_UNIT_TERABYTE; i++) {
79 if(strcasecmp(col_arg, unit_suffix[i]) == 0) {
80 tbl->column_order[col_inst_idx].output_type = i | SIZE_UNITS_FIXED;
84 if(tbl->column_order[col_inst_idx].output_type == XTYPE_FMT_DEFAULT) {
85 *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d (counted from 0)", col_arg, col_inst_idx);
90 return TABLE_OPT_PROCESSED;
93 TABLE_COL_BODY(size, u64)
95 const struct xtype xt_size = {
98 //.parse = xt_size_parse,
99 .format = xt_size_format,
104 #define FORMAT_TIME_SIZE 20 // Minimum buffer size
106 int table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
108 int col_type_idx = tbl->column_order[col_inst_idx].idx;
109 if(tbl->columns[col_type_idx].type_def != &xt_timestamp) {
111 return TABLE_OPT_UNKNOWN;
114 if(col_arg == NULL) {
115 *err = "NULL is not supported as a column argument.";
116 return TABLE_OPT_ERR;
119 if(strcasecmp(col_arg, "timestamp") == 0 || strcasecmp(col_arg, "epoch") == 0) {
120 tbl->column_order[col_inst_idx].output_type = TIMESTAMP_EPOCH;
121 } else if(strcasecmp(col_arg, "datetime") == 0) {
122 tbl->column_order[col_inst_idx].output_type = TIMESTAMP_DATETIME;
124 *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d.", col_arg, col_inst_idx);
125 return TABLE_OPT_ERR;
129 return TABLE_OPT_PROCESSED;
132 static const char *xt_timestamp_format(void *src, u32 fmt, struct mempool *pool)
134 char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
136 u64 tmp_time_u64 = *(u64*)src;
137 time_t tmp_time = (time_t) tmp_time_u64;
138 struct tm t = *gmtime(&tmp_time);
140 case XTYPE_FMT_DEFAULT:
142 sprintf(formatted_time_buf, "%"PRIu64, tmp_time_u64);
144 case XTYPE_FMT_PRETTY:
145 strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
152 return mp_printf(pool, "%s", formatted_time_buf);
155 TABLE_COL_BODY(timestamp, u64)
157 const struct xtype xt_timestamp = {
160 //.parse = xt_timestamp_parse,
161 .format = xt_timestamp_format,