51 broke -E logic completely, rewise it
[tfcrypt.git] / tfc_conv.c
1 /*
2  * tfcrypt -- high security Threefish encryption tool.
3  *
4  * tfcrypt is copyrighted:
5  * Copyright (C) 2012-2019 Andrey Rys. All rights reserved.
6  *
7  * tfcrypt is licensed to you under the terms of std. MIT/X11 license:
8  *
9  * Permission is hereby granted, free of charge, to any person obtaining
10  * a copy of this software and associated documentation files (the
11  * "Software"), to deal in the Software without restriction, including
12  * without limitation the rights to use, copy, modify, merge, publish,
13  * distribute, sublicense, and/or sell copies of the Software, and to
14  * permit persons to whom the Software is furnished to do so, subject to
15  * the following conditions:
16  *
17  * The above copyright notice and this permission notice shall be
18  * included in all copies or substantial portions of the Software.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27  */
28
29 #include "tfcrypt.h"
30
31 static const char *tfc_size_scale[] = {"B", "K", "M", "G", "T", "P"};
32
33 void tfc_data_to_words64(void *data, size_t szdata)
34 {
35 #ifndef TF_NO_ENDIAN
36         size_t idx;
37         uint64_t *d = data;
38         uint64_t t;
39
40         for (idx = 0; idx < (szdata/sizeof(uint64_t)); idx++) {
41 #ifdef TF_BIG_ENDIAN
42                 t = htobe64(d[idx]);
43 #else
44                 t = htole64(d[idx]);
45 #endif
46                 d[idx] = t;
47         }
48 #endif
49 }
50
51 static tfc_yesno tfc_is_number(const char *s)
52 {
53         char *p;
54         if (!s || str_empty(s)) return NO;
55         strtol(s, &p, 10);
56         return str_empty(p) ? YES : NO;
57 }
58
59 tfc_fsize tfc_humanfsize(const char *s, char **stoi)
60 {
61         char pfx[2], T[2], N[48], *ss;
62         int base = 10;
63         size_t l;
64         tfc_fsize gbgib = 0, ret = 0;
65
66         if (!s) return 0;
67
68         memset(N, 0, sizeof(N));
69         memset(pfx, 0, sizeof(pfx));
70         memset(T, 0, sizeof(T));
71
72         if (!strncmp(s, "0x", 2)) {
73                 s += 2;
74                 base = 16;
75         }
76         else if (s[0] == '0') base = 0;
77
78         l = strnlen(s, sizeof(N)-1);
79         memcpy(N, s, l);
80
81         ss = strchr(N, ':');
82         if (ss && ss[1] && (ss[1] == '+' || ss[1] == '-' || ss[1] == '*' || ss[1] == '/')) {
83                 ss[0] = 0;
84                 l = strnlen(N, sizeof(N)-1);
85         }
86
87         if (base == 16) goto _nopfx;
88
89         pfx[0] = N[l-1];
90         if (tfc_is_number(pfx) == NO) N[l-1] = 0;
91
92 _nopfx:
93         *stoi = NULL;
94         if (tfc_is_number(pfx) || pfx[0] == 'B' || pfx[0] == 'c') ret = strtoull(N, stoi, base);
95         else if (pfx[0] == 'W') ret = strtoull(N, stoi, base)*2;
96         else if (pfx[0] == 'I') ret = strtoull(N, stoi, base)*4;
97         else if (pfx[0] == 'L') ret = strtoull(N, stoi, base)*8;
98         else if (pfx[0] == 'e') ret = strtoull(N, stoi, base)*TF_BLOCK_SIZE;
99         else if (pfx[0] == 'y') ret = strtoull(N, stoi, base)*TF_FROM_BITS(TFC_KEY_BITS);
100         else if (pfx[0] == 'x') ret = strtoull(N, stoi, base)*TF_FROM_BITS(TFC_KEY_BITS)*2;
101         else if (pfx[0] == 'E') ret = strtoull(N, stoi, base)*blksize;
102         else if (pfx[0] == 'b' || pfx[0] == 's') ret = strtoull(N, stoi, base)*512;
103         else if (pfx[0] == 'p' || pfx[0] == 'S') ret = strtoull(N, stoi, base)*4096;
104         else if (pfx[0] == 'k' || pfx[0] == 'K') {
105                 gbgib = do_stats_in_gibs == YES ? 1000 : 1024;
106         }
107         else if (pfx[0] == 'm' || pfx[0] == 'M') {
108                 gbgib = do_stats_in_gibs == YES ? 1000 * 1000 : 1024 * 1024;
109         }
110         else if (pfx[0] == 'g' || pfx[0] == 'G') {
111                 gbgib = do_stats_in_gibs == YES ? 1000 * 1000 * 1000 : 1024 * 1024 * 1024;
112         }
113         else if (pfx[0] == 'T') {
114                 gbgib = do_stats_in_gibs == YES ? 1000000000000ULL : 1099511627776ULL;
115         }
116         else if (pfx[0] == 'P') {
117                 gbgib = do_stats_in_gibs == YES ? 1000000000000000ULL : 1125899906842624ULL;
118         }
119         else ret = strtoull(N, stoi, base);
120         if (gbgib) ret = strtoull(N, stoi, base) * gbgib;
121
122         return ret;
123 }
124
125 const char *tfc_getscale(int scale)
126 {
127         return scale >= TFC_ARRAY_SIZE(tfc_size_scale) ?
128                 tfc_size_scale[TFC_ARRAY_SIZE(tfc_size_scale)-1] : tfc_size_scale[scale];
129 }
130
131 void tfc_describescale(tfc_fsize num, double *w, int *scale)
132 {
133         tfc_fsize gbgib = (do_stats_in_gibs == YES) ? 1000 : 1024;
134
135         if (num <= gbgib) {
136                 *w = num;
137                 *scale = 0;
138         }
139         else if ((num > gbgib)
140                 && (num <= gbgib * gbgib)) {
141                 *w = (double)num / gbgib;
142                 *scale = 1;
143         }
144         else if ((num > gbgib * gbgib)
145                 && (num <= gbgib * gbgib * gbgib)) {
146                 *w = (double)num / (gbgib * gbgib);
147                 *scale = 2;
148         }
149         else if ((num > gbgib * gbgib * gbgib)
150                 && (num <= gbgib * gbgib * gbgib * gbgib)) {
151                 *w = (double)num / (gbgib * gbgib * gbgib);
152                 *scale = 3;
153         }
154         else if ((num > gbgib * gbgib * gbgib * gbgib)
155                 && num <= gbgib * gbgib * gbgib * gbgib * gbgib) {
156                 *w = (double)num/ (gbgib * gbgib * gbgib * gbgib);
157                 *scale = 4;
158         }
159         else {
160                 *w = (double)num / (gbgib * gbgib * gbgib * gbgib * gbgib);
161                 *scale = 5;
162         }
163 }