]> mj.ucw.cz Git - libucw.git/blob - ucw/table-types.c
tableprinter: update of parsing of column options
[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 static const char * xt_size_fmt_parse(const char *opt_str, u32 *dest, struct mempool *pool UNUSED)
59 {
60   if(opt_str == NULL) {
61     return "NULL is not supported as a column argument.";
62   }
63
64   if(strlen(opt_str) == 0 || strcasecmp(opt_str, "b") == 0 || strcasecmp(opt_str, "bytes") == 0) {
65     *dest = SIZE_UNIT_BYTE | SIZE_UNITS_FIXED;
66     return NULL;
67   }
68
69   for(uint i = SIZE_UNIT_BYTE; i <= SIZE_UNIT_TERABYTE; i++) {
70     if(strcasecmp(opt_str, unit_suffix[i]) == 0) {
71       *dest = i | SIZE_UNITS_FIXED;
72       return NULL;
73     }
74   }
75
76   return "Unknown option.";
77 }
78
79 TABLE_COL_BODY(size, u64)
80
81 const struct xtype xt_size = {
82   .size = sizeof(u64),
83   .name = "size",
84   //.parse = xt_size_parse,
85   .format = xt_size_format,
86   .parse_fmt = xt_size_fmt_parse
87 };
88
89 /** xt_timestamp **/
90
91 #define FORMAT_TIME_SIZE 20     // Minimum buffer size
92
93 static const char *xt_timestamp_format(void *src, u32 fmt, struct mempool *pool)
94 {
95   char formatted_time_buf[FORMAT_TIME_SIZE] = { 0 };
96
97   u64 tmp_time_u64 = *(u64*)src;
98   time_t tmp_time = (time_t) tmp_time_u64;
99   struct tm t = *gmtime(&tmp_time);
100   switch (fmt) {
101   case XTYPE_FMT_DEFAULT:
102   case XTYPE_FMT_RAW:
103     sprintf(formatted_time_buf, "%"PRIu64, tmp_time_u64);
104     break;
105   case XTYPE_FMT_PRETTY:
106     strftime(formatted_time_buf, FORMAT_TIME_SIZE, "%F %T", &t);
107     break;
108   default:
109     ASSERT(0);
110     break;
111   }
112
113   return mp_printf(pool, "%s", formatted_time_buf);
114 }
115
116 static const char * xt_timestamp_fmt_parse(const char *opt_str, u32 *dest, struct mempool *pool)
117 {
118   if(opt_str == NULL) {
119     return "NULL is not supported as a column argument.";
120   }
121
122   if(strcasecmp(opt_str, "timestamp") == 0 || strcasecmp(opt_str, "epoch") == 0) {
123     *dest = TIMESTAMP_EPOCH;
124     return NULL;
125   } else if(strcasecmp(opt_str, "datetime") == 0) {
126     *dest = TIMESTAMP_DATETIME;
127     return NULL;
128   }
129
130   return mp_printf(pool, "Invalid column format option: '%s'.", opt_str);
131 }
132
133 TABLE_COL_BODY(timestamp, u64)
134
135 const struct xtype xt_timestamp = {
136   .size = sizeof(u64),
137   .name = "timestamp",
138   //.parse = xt_timestamp_parse,
139   .format = xt_timestamp_format,
140   .parse_fmt = xt_timestamp_fmt_parse
141 };