ef5d4fd934038e69d5caa34e7334a308d9e7fe54
[xfstests-dev.git] / lib / str_to_bytes.c
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write the Free Software Foundation,
16  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 #include <stdio.h>
19 #include <sys/param.h>
20 #include "str_to_bytes.h"
21
22 /****************************************************************************
23  * str_to_bytes(s)
24  *
25  * Computes the number of bytes described by string s.  s is assumed to be
26  * a base 10 positive (ie. >= 0) number followed by an optional single
27  * character multiplier.  The following multipliers are supported:
28  *
29  *              char    mult
30  *              -----------------
31  *              b       BSIZE  or BBSIZE
32  *              k       1024 bytes
33  *              K       1024 * sizeof(long)
34  *              m       2^20 (1048576)
35  *              M       2^20 (1048576 * sizeof(long)
36  *              g       2^30 (1073741824)
37  *              G       2^30 (1073741824) * sizeof(long)
38  *
39  * for instance, "1k" and "1024" would both cause str_to_bytes to return 1024.
40  *
41  * Returns -1 if mult is an invalid character, or if the integer portion of
42  * s is not a positive integer.
43  *
44  ****************************************************************************/
45
46 #if linux
47 #define B_MULT  DEV_BSIZE       /* block size */
48 #endif
49
50
51 #define K_MULT  1024            /* Kilo or 2^10 */
52 #define M_MULT  1048576         /* Mega or 2^20 */
53 #define G_MULT  1073741824      /* Giga or 2^30 */
54 #define T_MULT  1099511627776   /* tera or 2^40 */
55
56 int
57 str_to_bytes(s)
58 char    *s;
59 {
60     char    mult, junk;
61     int     nconv;
62     float   num;
63
64     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
65     if (nconv == 0 || nconv == 3 )
66         return -1;
67
68     if (nconv == 1)
69         return num;
70
71     switch (mult) {
72     case 'b':
73                 return (int)(num * (float)B_MULT);
74     case 'k':
75                 return (int)(num * (float)K_MULT);
76     case 'K':
77                 return (int)((num * (float)K_MULT) * sizeof(long));
78     case 'm':
79                 return (int)(num * (float)M_MULT);
80     case 'M':
81                 return (int)((num * (float)M_MULT) * sizeof(long));
82     case 'g':
83                 return (int)(num * (float)G_MULT);
84     case 'G':   
85                 return (int)((num * (float)G_MULT) * sizeof(long));
86     default:
87         return -1;
88     }
89 }
90
91 long
92 str_to_lbytes(s)
93 char    *s;
94 {
95     char    mult, junk;
96     long    nconv;
97     float   num;
98
99     nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
100     if (nconv == 0 || nconv == 3 )
101         return -1;
102
103     if (nconv == 1)
104         return (long)num;
105
106     switch (mult) {
107     case 'b':
108                 return (long)(num * (float)B_MULT);
109     case 'k':
110                 return (long)(num * (float)K_MULT);
111     case 'K':
112                 return (long)((num * (float)K_MULT) * sizeof(long));
113     case 'm':
114                 return (long)(num * (float)M_MULT);
115     case 'M':
116                 return (long)((num * (float)M_MULT) * sizeof(long));
117     case 'g':
118                 return (long)(num * (float)G_MULT);
119     case 'G':   
120                 return (long)((num * (float)G_MULT) * sizeof(long));
121     default:
122         return -1;
123     }
124 }
125
126 /*
127  * Force 64 bits number when compiled as a 32-bit binary.
128  * This allows for a number bigger than 2G.
129  */
130
131 long long
132 str_to_llbytes(s)
133 char    *s;
134 {
135     char    mult, junk;
136     long    nconv;
137     double  num;
138
139     nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
140     if (nconv == 0 || nconv == 3 )
141         return -1;
142
143     if (nconv == 1)
144         return (long long)num;
145
146     switch (mult) {
147     case 'b':
148                 return (long long)(num * (float)B_MULT);
149     case 'k':
150                 return (long long)(num * (float)K_MULT);
151     case 'K':
152                 return (long long)((num * (float)K_MULT) * sizeof(long long));
153     case 'm':
154                 return (long long)(num * (float)M_MULT);
155     case 'M':
156                 return (long long)((num * (float)M_MULT) * sizeof(long long));
157     case 'g':
158                 return (long long)(num * (float)G_MULT);
159     case 'G':   
160                 return (long long)((num * (float)G_MULT) * sizeof(long long));
161     default:
162         return -1;
163     }
164 }
165
166 #ifdef UNIT_TEST
167
168 main(int argc, char **argv)
169 {
170     int ind;
171
172     if (argc == 1 ) {
173         fprintf(stderr, "missing str_to_bytes() parameteres\n");
174         exit(1);
175     }
176    
177     for (ind=1; ind<argc; ind++) {
178
179         printf("str_to_bytes(%s) returned %d\n", 
180             argv[ind], str_to_bytes(argv[ind]));
181
182         printf("str_to_lbytes(%s) returned %ld\n", 
183             argv[ind], str_to_lbytes(argv[ind]));
184
185         printf("str_to_llbytes(%s) returned %lld\n", 
186             argv[ind], str_to_llbytes(argv[ind]));
187     }
188 }
189
190 #endif