Annotation of embedaddon/iperf/src/units.c, revision 1.1.1.1

1.1       misho       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>