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 73int 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 121long 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 */ 173long 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