1 /*
2 * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
31 */
32 #include <stdio.h>
33 #include <sys/param.h>
34
35 #include "bytes_by_prefix.h"
36
37 /****************************************************************************
38 * bytes_by_prefix(s)
39 *
40 * Computes the number of bytes described by string s. s is assumed to be
41 * a base 10 positive (ie. >= 0) number followed by an optional single
42 * character multiplier. The following multipliers are supported:
43 *
44 * char mult
45 * -----------------
46 * b BSIZE or BBSIZE
47 * k 1024 bytes
48 * K 1024 * sizeof(long)
49 * m 2^20 (1048576)
50 * M 2^20 (1048576 * sizeof(long)
51 * g 2^30 (1073741824)
52 * G 2^30 (1073741824) * sizeof(long)
53 *
54 * for instance, "1k" and "1024" would both cause bytes_by_prefix to return 1024
55 *
56 * Returns -1 if mult is an invalid character, or if the integer portion of
57 * s is not a positive integer.
58 *
59 ****************************************************************************/
60
61 #ifdef DEV_BSIZE
62 #define B_MULT DEV_BSIZE /* block size */
63 #else
64 #warning DEV_BSIZE is not defined, defaulting to 512
65 #define B_MULT 512
66 #endif
67
68 #define K_MULT 1024 /* Kilo or 2^10 */
69 #define M_MULT 1048576 /* Mega or 2^20 */
70 #define G_MULT 1073741824 /* Giga or 2^30 */
71 #define T_MULT 1099511627776 /* tera or 2^40 */
72
bytes_by_prefix(char * s)73 int bytes_by_prefix(char *s)
74 {
75 char mult, junk;
76 int nconv;
77 float num;
78 int result;
79
80 nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
81 if (nconv == 0 || nconv == 3)
82 return -1;
83
84 if (nconv == 1) {
85 result = num;
86 return result < 0 ? -1 : result;
87 }
88
89 switch (mult) {
90 case 'b':
91 result = (int)(num * (float)B_MULT);
92 break;
93 case 'k':
94 result = (int)(num * (float)K_MULT);
95 break;
96 case 'K':
97 result = (int)((num * (float)K_MULT) * sizeof(long));
98 break;
99 case 'm':
100 result = (int)(num * (float)M_MULT);
101 break;
102 case 'M':
103 result = (int)((num * (float)M_MULT) * sizeof(long));
104 break;
105 case 'g':
106 result = (int)(num * (float)G_MULT);
107 break;
108 case 'G':
109 result = (int)((num * (float)G_MULT) * sizeof(long));
110 break;
111 default:
112 return -1;
113 }
114
115 if (result < 0)
116 return -1;
117
118 return result;
119 }
120
lbytes_by_prefix(char * s)121 long lbytes_by_prefix(char *s)
122 {
123 char mult, junk;
124 int nconv;
125 float num;
126 long result;
127
128 nconv = sscanf(s, "%f%c%c", &num, &mult, &junk);
129 if (nconv == 0 || nconv == 3)
130 return -1;
131
132 if (nconv == 1) {
133 result = (long)num;
134 return result < 0 ? -1 : result;
135 }
136
137 switch (mult) {
138 case 'b':
139 result = (long)(num * (float)B_MULT);
140 break;
141 case 'k':
142 result = (long)(num * (float)K_MULT);
143 break;
144 case 'K':
145 result = (long)((num * (float)K_MULT) * sizeof(long));
146 break;
147 case 'm':
148 result = (long)(num * (float)M_MULT);
149 break;
150 case 'M':
151 result = (long)((num * (float)M_MULT) * sizeof(long));
152 break;
153 case 'g':
154 result = (long)(num * (float)G_MULT);
155 break;
156 case 'G':
157 result = (long)((num * (float)G_MULT) * sizeof(long));
158 break;
159 default:
160 return -1;
161 }
162
163 if (result < 0)
164 return -1;
165
166 return result;
167 }
168
169 /*
170 * Force 64 bits number when compiled as 32 IRIX binary.
171 * This allows for a number bigger than 2G.
172 */
llbytes_by_prefix(char * s)173 long long llbytes_by_prefix(char *s)
174 {
175 char mult, junk;
176 int nconv;
177 double num;
178 long long result;
179
180 nconv = sscanf(s, "%lf%c%c", &num, &mult, &junk);
181 if (nconv == 0 || nconv == 3)
182 return -1;
183 if (nconv == 1) {
184 result = (long long)num;
185 return result < 0 ? -1 : result;
186 }
187
188 switch (mult) {
189 case 'b':
190 result = (long long)(num * (float)B_MULT);
191 break;
192 case 'k':
193 result = (long long)(num * (float)K_MULT);
194 break;
195 case 'K':
196 result = (long long)((num * (float)K_MULT) * sizeof(long long));
197 break;
198 case 'm':
199 result = (long long)(num * (float)M_MULT);
200 break;
201 case 'M':
202 result = (long long)((num * (float)M_MULT) * sizeof(long long));
203 break;
204 case 'g':
205 result = (long long)(num * (float)G_MULT);
206 break;
207 case 'G':
208 result = (long long)((num * (float)G_MULT) * sizeof(long long));
209 break;
210 default:
211 return -1;
212 }
213
214 if (result < 0)
215 return -1;
216
217 return result;
218 }
219