File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / iperf / src / units.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Oct 18 13:28:18 2016 UTC (7 years, 9 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>