1d18ce8e9SJon Dugan /*--------------------------------------------------------------- 2d18ce8e9SJon Dugan * Copyright (c) 1999,2000,2001,2002,2003 3d18ce8e9SJon Dugan * The Board of Trustees of the University of Illinois 4d18ce8e9SJon Dugan * All Rights Reserved. 5d18ce8e9SJon Dugan *--------------------------------------------------------------- 6d18ce8e9SJon Dugan * Permission is hereby granted, free of charge, to any person 7d18ce8e9SJon Dugan * obtaining a copy of this software (Iperf) and associated 8d18ce8e9SJon Dugan * documentation files (the "Software"), to deal in the Software 9d18ce8e9SJon Dugan * without restriction, including without limitation the 10d18ce8e9SJon Dugan * rights to use, copy, modify, merge, publish, distribute, 11d18ce8e9SJon Dugan * sublicense, and/or sell copies of the Software, and to permit 12d18ce8e9SJon Dugan * persons to whom the Software is furnished to do 13d18ce8e9SJon Dugan * so, subject to the following conditions: 14d18ce8e9SJon Dugan * 15d18ce8e9SJon Dugan * 16d18ce8e9SJon Dugan * Redistributions of source code must retain the above 17d18ce8e9SJon Dugan * copyright notice, this list of conditions and 18d18ce8e9SJon Dugan * the following disclaimers. 19d18ce8e9SJon Dugan * 20d18ce8e9SJon Dugan * 21d18ce8e9SJon Dugan * Redistributions in binary form must reproduce the above 22d18ce8e9SJon Dugan * copyright notice, this list of conditions and the following 23d18ce8e9SJon Dugan * disclaimers in the documentation and/or other materials 24d18ce8e9SJon Dugan * provided with the distribution. 25d18ce8e9SJon Dugan * 26d18ce8e9SJon Dugan * 27d18ce8e9SJon Dugan * Neither the names of the University of Illinois, NCSA, 28d18ce8e9SJon Dugan * nor the names of its contributors may be used to endorse 29d18ce8e9SJon Dugan * or promote products derived from this Software without 30d18ce8e9SJon Dugan * specific prior written permission. 31d18ce8e9SJon Dugan * 32d18ce8e9SJon Dugan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 33d18ce8e9SJon Dugan * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 34d18ce8e9SJon Dugan * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 35d18ce8e9SJon Dugan * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT 36d18ce8e9SJon Dugan * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 37d18ce8e9SJon Dugan * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 38d18ce8e9SJon Dugan * ARISING FROM, OUT OF OR IN CONNECTION WITH THE 39d18ce8e9SJon Dugan * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 40d18ce8e9SJon Dugan * ________________________________________________________________ 41d18ce8e9SJon Dugan * National Laboratory for Applied Network Research 42d18ce8e9SJon Dugan * National Center for Supercomputing Applications 43d18ce8e9SJon Dugan * University of Illinois at Urbana-Champaign 44d18ce8e9SJon Dugan * http://www.ncsa.uiuc.edu 45d18ce8e9SJon Dugan * ________________________________________________________________ 46d18ce8e9SJon Dugan * 47d18ce8e9SJon Dugan * stdio.c 48d18ce8e9SJon Dugan * by Mark Gates <[email protected]> 49d18ce8e9SJon Dugan * and Ajay Tirumalla <[email protected]> 50d18ce8e9SJon Dugan * ------------------------------------------------------------------- 51e9e2d6d1SBruce A. Mah * input and output numbers, converting with kilo, mega, giga, tera 52d18ce8e9SJon Dugan * ------------------------------------------------------------------- */ 53d18ce8e9SJon Dugan 54e9287700SJon Dugan #include <stdio.h> 55e9287700SJon Dugan #include <assert.h> 56e9287700SJon Dugan #include <ctype.h> 57426221a3SBruce A. Mah #ifdef HAVE_STDINT_H 58e9287700SJon Dugan #include <stdint.h> 59426221a3SBruce A. Mah #endif 60a951c980SBrian Tierney #include <sys/socket.h> 61c95ee19cSHavard Eidnes #include <sys/types.h> 62a951c980SBrian Tierney #include <sys/time.h> 638d41fbd7SBrian Tierney 64e9287700SJon Dugan 65e9287700SJon Dugan #include "iperf.h" 66d18ce8e9SJon Dugan 67d18ce8e9SJon Dugan #ifdef __cplusplus 68e434aab6SBrian Tierney extern "C" 69e434aab6SBrian Tierney { 70d18ce8e9SJon Dugan #endif 71d18ce8e9SJon Dugan 72c8531ca3SBruce A. Mah const double KILO_UNIT = 1024.0; 73c8531ca3SBruce A. Mah const double MEGA_UNIT = 1024.0 * 1024.0; 74c8531ca3SBruce A. Mah const double GIGA_UNIT = 1024.0 * 1024.0 * 1024.0; 75c8531ca3SBruce A. Mah const double TERA_UNIT = 1024.0 * 1024.0 * 1024.0 * 1024.0; 76d18ce8e9SJon Dugan 77c8531ca3SBruce A. Mah const double KILO_RATE_UNIT = 1000.0; 78c8531ca3SBruce A. Mah const double MEGA_RATE_UNIT = 1000.0 * 1000.0; 79c8531ca3SBruce A. Mah const double GIGA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0; 80c8531ca3SBruce A. Mah const double TERA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0 * 1000.0; 81f5062770SBruce A. Mah 82d18ce8e9SJon Dugan /* ------------------------------------------------------------------- 83e9287700SJon Dugan * unit_atof 84d18ce8e9SJon Dugan * 85d18ce8e9SJon Dugan * Given a string of form #x where # is a number and x is a format 86d18ce8e9SJon Dugan * character listed below, this returns the interpreted integer. 87d18ce8e9SJon Dugan * Gg, Mm, Kk are giga, mega, kilo respectively 88d18ce8e9SJon Dugan * ------------------------------------------------------------------- */ 89d18ce8e9SJon Dugan unit_atof(const char * s)90e434aab6SBrian Tierney double unit_atof(const char *s) 91e434aab6SBrian Tierney { 92e9287700SJon Dugan double n; 93d18ce8e9SJon Dugan char suffix = '\0'; 94d18ce8e9SJon Dugan 95e9287700SJon Dugan assert(s != NULL); 96d18ce8e9SJon Dugan 97d18ce8e9SJon Dugan /* scan the number and any suffices */ 98e9287700SJon Dugan sscanf(s, "%lf%c", &n, &suffix); 99d18ce8e9SJon Dugan 100e9e2d6d1SBruce A. Mah /* convert according to [Tt Gg Mm Kk] */ 101e434aab6SBrian Tierney switch (suffix) 102e434aab6SBrian Tierney { 103e9e2d6d1SBruce A. Mah case 't': case 'T': 104e9e2d6d1SBruce A. Mah n *= TERA_UNIT; 105e9e2d6d1SBruce A. Mah break; 1062efc602fSJef Poskanzer case 'g': case 'G': 107e434aab6SBrian Tierney n *= GIGA_UNIT; 108e434aab6SBrian Tierney break; 1092efc602fSJef Poskanzer case 'm': case 'M': 110e434aab6SBrian Tierney n *= MEGA_UNIT; 111e434aab6SBrian Tierney break; 1122efc602fSJef Poskanzer case 'k': case 'K': 113e434aab6SBrian Tierney n *= KILO_UNIT; 114e434aab6SBrian Tierney break; 115e434aab6SBrian Tierney default: 116e434aab6SBrian Tierney break; 117d18ce8e9SJon Dugan } 118e9287700SJon Dugan return n; 119e9287700SJon Dugan } /* end unit_atof */ 120d18ce8e9SJon Dugan 121f5062770SBruce A. Mah 122f5062770SBruce A. Mah /* ------------------------------------------------------------------- 123f5062770SBruce A. Mah * unit_atof_rate 124f5062770SBruce A. Mah * 125f5062770SBruce A. Mah * Similar to unit_atof, but uses 10-based rather than 2-based 126f5062770SBruce A. Mah * suffixes. 127f5062770SBruce A. Mah * ------------------------------------------------------------------- */ 128f5062770SBruce A. Mah unit_atof_rate(const char * s)129f5062770SBruce A. Mah double unit_atof_rate(const char *s) 130f5062770SBruce A. Mah { 131f5062770SBruce A. Mah double n; 132f5062770SBruce A. Mah char suffix = '\0'; 133f5062770SBruce A. Mah 134f5062770SBruce A. Mah assert(s != NULL); 135f5062770SBruce A. Mah 136f5062770SBruce A. Mah /* scan the number and any suffices */ 137f5062770SBruce A. Mah sscanf(s, "%lf%c", &n, &suffix); 138f5062770SBruce A. Mah 139e9e2d6d1SBruce A. Mah /* convert according to [Tt Gg Mm Kk] */ 140f5062770SBruce A. Mah switch (suffix) 141f5062770SBruce A. Mah { 142e9e2d6d1SBruce A. Mah case 't': case 'T': 143e9e2d6d1SBruce A. Mah n *= TERA_RATE_UNIT; 144e9e2d6d1SBruce A. Mah break; 145f5062770SBruce A. Mah case 'g': case 'G': 146f5062770SBruce A. Mah n *= GIGA_RATE_UNIT; 147f5062770SBruce A. Mah break; 148f5062770SBruce A. Mah case 'm': case 'M': 149f5062770SBruce A. Mah n *= MEGA_RATE_UNIT; 150f5062770SBruce A. Mah break; 151f5062770SBruce A. Mah case 'k': case 'K': 152f5062770SBruce A. Mah n *= KILO_RATE_UNIT; 153f5062770SBruce A. Mah break; 154f5062770SBruce A. Mah default: 155f5062770SBruce A. Mah break; 156f5062770SBruce A. Mah } 157f5062770SBruce A. Mah return n; 158f5062770SBruce A. Mah } /* end unit_atof_rate */ 159f5062770SBruce A. Mah 160f5062770SBruce A. Mah 161f5062770SBruce A. Mah 162d18ce8e9SJon Dugan /* ------------------------------------------------------------------- 163e9287700SJon Dugan * unit_atoi 164d18ce8e9SJon Dugan * 165d18ce8e9SJon Dugan * Given a string of form #x where # is a number and x is a format 166d18ce8e9SJon Dugan * character listed below, this returns the interpreted integer. 167e9e2d6d1SBruce A. Mah * Tt, Gg, Mm, Kk are tera, giga, mega, kilo respectively 168d18ce8e9SJon Dugan * ------------------------------------------------------------------- */ 169d18ce8e9SJon Dugan unit_atoi(const char * s)170e434aab6SBrian Tierney iperf_size_t unit_atoi(const char *s) 171e434aab6SBrian Tierney { 172e9287700SJon Dugan double n; 173d18ce8e9SJon Dugan char suffix = '\0'; 174d18ce8e9SJon Dugan 175e9287700SJon Dugan assert(s != NULL); 176d18ce8e9SJon Dugan 177d18ce8e9SJon Dugan /* scan the number and any suffices */ 178e9287700SJon Dugan sscanf(s, "%lf%c", &n, &suffix); 179d18ce8e9SJon Dugan 180e9e2d6d1SBruce A. Mah /* convert according to [Tt Gg Mm Kk] */ 181e434aab6SBrian Tierney switch (suffix) 182e434aab6SBrian Tierney { 183e9e2d6d1SBruce A. Mah case 't': case 'T': 184e9e2d6d1SBruce A. Mah n *= TERA_UNIT; 185e9e2d6d1SBruce A. Mah break; 1862efc602fSJef Poskanzer case 'g': case 'G': 187e434aab6SBrian Tierney n *= GIGA_UNIT; 188e434aab6SBrian Tierney break; 1892efc602fSJef Poskanzer case 'm': case 'M': 190e434aab6SBrian Tierney n *= MEGA_UNIT; 191e434aab6SBrian Tierney break; 1922efc602fSJef Poskanzer case 'k': case 'K': 193e434aab6SBrian Tierney n *= KILO_UNIT; 194e434aab6SBrian Tierney break; 195e434aab6SBrian Tierney default: 196e434aab6SBrian Tierney break; 197d18ce8e9SJon Dugan } 198e9287700SJon Dugan return (iperf_size_t) n; 199e9287700SJon Dugan } /* end unit_atof */ 200d18ce8e9SJon Dugan 201d18ce8e9SJon Dugan /* ------------------------------------------------------------------- 202d18ce8e9SJon Dugan * constants for byte_printf 203d18ce8e9SJon Dugan * ------------------------------------------------------------------- */ 204d18ce8e9SJon Dugan 205e9287700SJon Dugan /* used as indices into conversion_bytes[], label_byte[], and label_bit[] */ 206e434aab6SBrian Tierney enum 207e434aab6SBrian Tierney { 208e9287700SJon Dugan UNIT_CONV, 209e9287700SJon Dugan KILO_CONV, 210e9287700SJon Dugan MEGA_CONV, 211e9e2d6d1SBruce A. Mah GIGA_CONV, 212e9e2d6d1SBruce A. Mah TERA_CONV 213d18ce8e9SJon Dugan }; 214d18ce8e9SJon Dugan 215d18ce8e9SJon Dugan /* factor to multiply the number by */ 216e9287700SJon Dugan const double conversion_bytes[] = 217d18ce8e9SJon Dugan { 218d18ce8e9SJon Dugan 1.0, /* unit */ 219d18ce8e9SJon Dugan 1.0 / 1024, /* kilo */ 220d18ce8e9SJon Dugan 1.0 / 1024 / 1024, /* mega */ 221e9e2d6d1SBruce A. Mah 1.0 / 1024 / 1024 / 1024, /* giga */ 222e9e2d6d1SBruce A. Mah 1.0 / 1024 / 1024 / 1024 / 1024 /* tera */ 223d18ce8e9SJon Dugan }; 224d18ce8e9SJon Dugan 225d18ce8e9SJon Dugan /* factor to multiply the number by for bits*/ 226e9287700SJon Dugan const double conversion_bits[] = 227d18ce8e9SJon Dugan { 228d18ce8e9SJon Dugan 1.0, /* unit */ 229d18ce8e9SJon Dugan 1.0 / 1000, /* kilo */ 230d18ce8e9SJon Dugan 1.0 / 1000 / 1000, /* mega */ 231e9e2d6d1SBruce A. Mah 1.0 / 1000 / 1000 / 1000, /* giga */ 232e9e2d6d1SBruce A. Mah 1.0 / 1000 / 1000 / 1000 / 1000 /* tera */ 233d18ce8e9SJon Dugan }; 234d18ce8e9SJon Dugan 235d18ce8e9SJon Dugan 236e9e2d6d1SBruce A. Mah /* labels for Byte formats [KMGT] */ 237e9287700SJon Dugan const char *label_byte[] = 238d18ce8e9SJon Dugan { 239d18ce8e9SJon Dugan "Byte", 240d18ce8e9SJon Dugan "KByte", 241d18ce8e9SJon Dugan "MByte", 242e9e2d6d1SBruce A. Mah "GByte", 243e9e2d6d1SBruce A. Mah "TByte" 244d18ce8e9SJon Dugan }; 245d18ce8e9SJon Dugan 246e9e2d6d1SBruce A. Mah /* labels for bit formats [kmgt] */ 247e9287700SJon Dugan const char *label_bit[] = 248d18ce8e9SJon Dugan { 249d18ce8e9SJon Dugan "bit", 250d18ce8e9SJon Dugan "Kbit", 251d18ce8e9SJon Dugan "Mbit", 252e9e2d6d1SBruce A. Mah "Gbit", 253e9e2d6d1SBruce A. Mah "Tbit" 254d18ce8e9SJon Dugan }; 255d18ce8e9SJon Dugan 256d18ce8e9SJon Dugan /* ------------------------------------------------------------------- 257e9287700SJon Dugan * unit_snprintf 258d18ce8e9SJon Dugan * 259d18ce8e9SJon Dugan * Given a number in bytes and a format, converts the number and 260d18ce8e9SJon Dugan * prints it out with a bits or bytes label. 261d18ce8e9SJon Dugan * B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte 262d18ce8e9SJon Dugan * b, k, m, g, a for bit, Kbit, Mbit, Gbit, adaptive bit 263d18ce8e9SJon Dugan * adaptive picks the "best" one based on the number. 264e9287700SJon Dugan * s should be at least 11 chars long 265d18ce8e9SJon Dugan * (4 digits + space + 5 chars max + null) 266d18ce8e9SJon Dugan * ------------------------------------------------------------------- */ 267d18ce8e9SJon Dugan unit_snprintf(char * s,int inLen,double inNum,char inFormat)268e9287700SJon Dugan void unit_snprintf(char *s, int inLen, 269e434aab6SBrian Tierney double inNum, char inFormat) 270e434aab6SBrian Tierney { 271d18ce8e9SJon Dugan int conv; 272d18ce8e9SJon Dugan const char *suffix; 273d18ce8e9SJon Dugan const char *format; 274d18ce8e9SJon Dugan 275d18ce8e9SJon Dugan /* convert to bits for [bkmga] */ 276e434aab6SBrian Tierney if (!isupper((int) inFormat)) 277e434aab6SBrian Tierney { 278d18ce8e9SJon Dugan inNum *= 8; 279d18ce8e9SJon Dugan } 280c95ee19cSHavard Eidnes switch (toupper((u_char)inFormat)) 281e434aab6SBrian Tierney { 282e434aab6SBrian Tierney case 'B': 283e434aab6SBrian Tierney conv = UNIT_CONV; 284e434aab6SBrian Tierney break; 285e434aab6SBrian Tierney case 'K': 286e434aab6SBrian Tierney conv = KILO_CONV; 287e434aab6SBrian Tierney break; 288e434aab6SBrian Tierney case 'M': 289e434aab6SBrian Tierney conv = MEGA_CONV; 290e434aab6SBrian Tierney break; 291e434aab6SBrian Tierney case 'G': 292e434aab6SBrian Tierney conv = GIGA_CONV; 293e434aab6SBrian Tierney break; 294e9e2d6d1SBruce A. Mah case 'T': 295e9e2d6d1SBruce A. Mah conv = TERA_CONV; 296e9e2d6d1SBruce A. Mah break; 297d18ce8e9SJon Dugan 298d18ce8e9SJon Dugan default: 299e434aab6SBrian Tierney case 'A': 300e434aab6SBrian Tierney { 301d18ce8e9SJon Dugan double tmpNum = inNum; 302e9287700SJon Dugan conv = UNIT_CONV; 303d18ce8e9SJon Dugan 304e434aab6SBrian Tierney if (isupper((int) inFormat)) 305e434aab6SBrian Tierney { 306*25f59475SBruce A. Mah while (tmpNum >= 1024.0 && conv < TERA_CONV) 307e434aab6SBrian Tierney { 308d18ce8e9SJon Dugan tmpNum /= 1024.0; 309d18ce8e9SJon Dugan conv++; 310d18ce8e9SJon Dugan } 311e434aab6SBrian Tierney } else 312e434aab6SBrian Tierney { 313*25f59475SBruce A. Mah while (tmpNum >= 1000.0 && conv < TERA_CONV) 314e434aab6SBrian Tierney { 315d18ce8e9SJon Dugan tmpNum /= 1000.0; 316d18ce8e9SJon Dugan conv++; 317d18ce8e9SJon Dugan } 318d18ce8e9SJon Dugan } 319d18ce8e9SJon Dugan break; 320d18ce8e9SJon Dugan } 321d18ce8e9SJon Dugan } 322d18ce8e9SJon Dugan 323e434aab6SBrian Tierney if (!isupper((int) inFormat)) 324e434aab6SBrian Tierney { 325e9287700SJon Dugan inNum *= conversion_bits[conv]; 326e9287700SJon Dugan suffix = label_bit[conv]; 327e434aab6SBrian Tierney } else 328e434aab6SBrian Tierney { 329e9287700SJon Dugan inNum *= conversion_bytes[conv]; 330e9287700SJon Dugan suffix = label_byte[conv]; 331d18ce8e9SJon Dugan } 332d18ce8e9SJon Dugan 333d18ce8e9SJon Dugan /* print such that we always fit in 4 places */ 334e434aab6SBrian Tierney if (inNum < 9.995) 335e434aab6SBrian Tierney { /* 9.995 would be rounded to 10.0 */ 336d18ce8e9SJon Dugan format = "%4.2f %s";/* #.## */ 337e434aab6SBrian Tierney } else if (inNum < 99.95) 338e434aab6SBrian Tierney { /* 99.95 would be rounded to 100 */ 339d18ce8e9SJon Dugan format = "%4.1f %s";/* ##.# */ 340e434aab6SBrian Tierney } else if (inNum < 999.5) 341e434aab6SBrian Tierney { /* 999.5 would be rounded to 1000 */ 342d18ce8e9SJon Dugan format = "%4.0f %s";/* ### */ 343e434aab6SBrian Tierney } else 344e434aab6SBrian Tierney { /* 1000-1024 fits in 4 places If not using 345e434aab6SBrian Tierney * Adaptive sizes then this code will not 346e434aab6SBrian Tierney * control spaces */ 347d18ce8e9SJon Dugan format = "%4.0f %s";/* #### */ 348d18ce8e9SJon Dugan } 349e9287700SJon Dugan snprintf(s, inLen, format, inNum, suffix); 350e9287700SJon Dugan } /* end unit_snprintf */ 351d18ce8e9SJon Dugan 352d18ce8e9SJon Dugan #ifdef __cplusplus 353d18ce8e9SJon Dugan } /* end extern "C" */ 354e434aab6SBrian Tierney 355d18ce8e9SJon Dugan #endif 356