]> mj.ucw.cz Git - libucw.git/blob - ucw/table-types.c
tableprinter: removed unnecessary macros, code cleanup
[libucw.git] / ucw / table-types.c
1 /*
2  *      UCW Library -- Table printer types
3  *
4  *      (c) 2014 Robert Kessl <robert.kessl@economia.cz>
5  */
6
7 #include <ucw/lib.h>
8 #include <ucw/table-types.h>
9 #include <ucw/fastbuf.h>
10 #include <ucw/table.h>
11 #include <time.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <inttypes.h>
15
16 /** xt_size **/
17
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"
24 };
25
26 static const char *xt_size_format(void *src, u32 fmt, struct mempool *pool)
27 {
28   u64 curr_val = *(u64*) src;
29
30   if(fmt == XTYPE_FMT_RAW) {
31     return mp_printf(pool, "%"PRIu64, curr_val);
32   }
33
34   uint out_type = SIZE_UNIT_BYTE;
35
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
42   };
43
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;
53   }
54
55   return mp_printf(pool, "%"PRIu64"%s", curr_val, unit_suffix[out_type]);
56 }
57
58 int table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
59 {
60   if(col_arg == NULL) {
61     *err = "NULL is not supported as a column argument.";
62     return TABLE_OPT_ERR;
63   }
64
65   const struct table_column *col_def = tbl->column_order[col_inst_idx].col_def;
66   if(col_def->type_def != &xt_size) {
67     *err = NULL;
68     return TABLE_OPT_UNKNOWN;
69   }
70
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;
73     *err = NULL;
74     return TABLE_OPT_PROCESSED;
75   }
76
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;
81     }
82   }
83
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);
86     return TABLE_OPT_ERR;
87   }
88
89   *err = NULL;
90   return TABLE_OPT_PROCESSED;
91 }
92
93 TABLE_COL_BODY(size, u64)
94
95 const struct xtype xt_size = {
96   .size = sizeof(u64),
97   .name = "size",
98   //.parse = xt_size_parse,
99   .format = xt_size_format,
100 };
101
102 /** xt_timestamp **/
103
104 #define FORMAT_TIME_SIZE 20     // Minimum buffer size
105
106 int table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
107 {
108   int col_type_idx = tbl->column_order[col_inst_idx].idx;
109   if(tbl->columns[col_type_idx].type_def != &xt_timestamp) {
110     *err = NULL;
111     return TABLE_OPT_UNKNOWN;
112   }
113
114   if(col_arg == NULL) {
115     *err = "NULL is not supported as a column argument.";
116     return TABLE_OPT_ERR;
117   }
118
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;
123   } else {
124     *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d.", col_arg, col_inst_idx);
125     return TABLE_OPT_ERR;
126   }
127
128   *err = NULL;
129   return TABLE_OPT_PROCESSED;
130 }
131
132 static const char *xt_timestamp_format(void *src, u32 fmt, struct mempool *pool)
133 {
134   char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
135
136   u64 tmp_time_u64 = *(u64*)src;
137   time_t tmp_time = (time_t) tmp_time_u64;
138   struct tm t = *gmtime(&tmp_time);
139   switch (fmt) {
140   case XTYPE_FMT_DEFAULT:
141   case XTYPE_FMT_RAW:
142     sprintf(formatted_time_buf, "%"PRIu64, tmp_time_u64);
143     break;
144   case XTYPE_FMT_PRETTY:
145     strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
146     break;
147   default:
148     ASSERT(0);
149     break;
150   }
151
152   return mp_printf(pool, "%s", formatted_time_buf);
153 }
154
155 TABLE_COL_BODY(timestamp, u64)
156
157 const struct xtype xt_timestamp = {
158   .size = sizeof(u64),
159   .name = "timestamp",
160   //.parse = xt_timestamp_parse,
161   .format = xt_timestamp_format,
162 };