]> mj.ucw.cz Git - libucw.git/blob - ucw/table-types.c
Merge remote-tracking branch 'origin/dev-table' into dev-table
[libucw.git] / ucw / table-types.c
1 #include <ucw/lib.h>
2 #include <ucw/table-types.h>
3 #include <ucw/fastbuf.h>
4 #include <ucw/table.h>
5 #include <time.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <inttypes.h>
9
10 /** xt_size **/
11
12 static const char *unit_suffix[] = {
13   [SIZE_UNIT_BYTE] = "",
14   [SIZE_UNIT_KILOBYTE] = "KB",
15   [SIZE_UNIT_MEGABYTE] = "MB",
16   [SIZE_UNIT_GIGABYTE] = "GB",
17   [SIZE_UNIT_TERABYTE] = "TB"
18 };
19
20 static const char *xt_size_format(void *src, u32 fmt, struct mempool *pool)
21 {
22   u64 curr_val = *(u64*) src;
23   uint out_type = SIZE_UNIT_BYTE;
24
25   static u64 unit_div[] = {
26     [SIZE_UNIT_BYTE] = 1LLU,
27     [SIZE_UNIT_KILOBYTE] = 1024LLU,
28     [SIZE_UNIT_MEGABYTE] = 1024LLU * 1024LLU,
29     [SIZE_UNIT_GIGABYTE] = 1024LLU * 1024LLU * 1024LLU,
30     [SIZE_UNIT_TERABYTE] = 1024LLU * 1024LLU * 1024LLU * 1024LLU
31   };
32
33   if(fmt == XTYPE_FMT_DEFAULT || fmt == XTYPE_FMT_RAW) {
34     curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
35     out_type = SIZE_UNIT_BYTE;
36   } else if(fmt == XTYPE_FMT_PRETTY) {
37     curr_val = curr_val / unit_div[SIZE_UNIT_BYTE];
38     out_type = SIZE_UNIT_BYTE;
39   } else if((fmt & SIZE_UNITS_FIXED) != 0) {
40     curr_val = curr_val / unit_div[fmt & ~SIZE_UNITS_FIXED];
41     out_type = fmt & ~SIZE_UNITS_FIXED;
42   }
43
44   return mp_printf(pool, "%"PRIu64"%s", curr_val, unit_suffix[out_type]);
45 }
46
47 bool table_set_col_opt_size(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
48 {
49   const struct table_column *col_def = tbl->column_order[col_inst_idx].col_def;
50   if(col_def->type_def != COL_TYPE_SIZE) {
51     *err = NULL;
52     return false;
53   }
54
55   if(col_arg == NULL || strcasecmp(col_arg, "b") == 0 || strcasecmp(col_arg, "bytes") == 0) {
56     tbl->column_order[col_inst_idx].output_type = SIZE_UNIT_BYTE | SIZE_UNITS_FIXED;
57     *err = NULL;
58     return true;
59   }
60
61   tbl->column_order[col_inst_idx].output_type = XTYPE_FMT_DEFAULT; // CELL_OUT_UNINITIALIZED;
62   for(uint i = SIZE_UNIT_BYTE; i <= SIZE_UNIT_TERABYTE; i++) {
63     if(strcasecmp(col_arg, unit_suffix[i]) == 0) {
64       tbl->column_order[col_inst_idx].output_type = i | SIZE_UNITS_FIXED;
65     }
66   }
67
68   if(tbl->column_order[col_inst_idx].output_type == XTYPE_FMT_DEFAULT) {
69     *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d (counted from 0)", col_arg, col_inst_idx);
70     return true;
71   }
72
73   *err = NULL;
74   return true;
75 }
76
77 TABLE_COL_BODY(size, u64)
78
79 const struct xtype xt_size = {
80   .size = sizeof(u64),
81   .name = "size",
82   //.parse = xt_size_parse,
83   .format = xt_size_format,
84 };
85
86 /** xt_timestamp **/
87
88 #define FORMAT_TIME_SIZE 20     // Minimum buffer size
89
90 bool table_set_col_opt_timestamp(struct table *tbl, uint col_inst_idx, const char *col_arg, char **err)
91 {
92   int col_type_idx = tbl->column_order[col_inst_idx].idx;
93   if(tbl->columns[col_type_idx].type_def != COL_TYPE_TIMESTAMP) {
94     *err = NULL;
95     return false;
96   }
97
98   if(col_arg == NULL) {
99     *err = NULL;
100     return true;
101   }
102
103   if(strcasecmp(col_arg, "timestamp") == 0 || strcasecmp(col_arg, "epoch") == 0) {
104     tbl->column_order[col_inst_idx].output_type = TIMESTAMP_EPOCH;
105   } else if(strcasecmp(col_arg, "datetime") == 0) {
106     tbl->column_order[col_inst_idx].output_type = TIMESTAMP_DATETIME;
107   } else {
108     *err = mp_printf(tbl->pool, "Invalid column format option: '%s' for column %d.", col_arg, col_inst_idx);
109     return true;
110   }
111
112   *err = NULL;
113   return true;
114 }
115
116 static const char *xt_timestamp_format(void *src, u32 fmt, struct mempool *pool)
117 {
118   char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
119
120   u64 tmp_time_u64 = *(u64*)src;
121   time_t tmp_time = (time_t) tmp_time_u64;
122   struct tm t = *gmtime(&tmp_time);
123   switch (fmt) {
124   case XTYPE_FMT_DEFAULT:
125   case XTYPE_FMT_RAW:
126     sprintf(formatted_time_buf, "%"PRIu64, tmp_time_u64);
127     break;
128   case XTYPE_FMT_PRETTY:
129     strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
130     break;
131   default:
132     ASSERT(0);
133     break;
134   }
135
136   return mp_printf(pool, "%s", formatted_time_buf);
137 }
138
139 TABLE_COL_BODY(timestamp, u64)
140
141 const struct xtype xt_timestamp = {
142   .size = sizeof(u64),
143   .name = "timestamp",
144   //.parse = xt_timestamp_parse,
145   .format = xt_timestamp_format,
146 };