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

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:  * -------------------------------------------------------------------
1.1.1.2 ! misho      51:  * input and output numbers, converting with kilo, mega, giga, tera
1.1       misho      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: 
                     64: 
                     65: #include "iperf.h"
                     66: 
                     67: #ifdef __cplusplus
                     68: extern    "C"
                     69: {
                     70: #endif
                     71: 
1.1.1.2 ! misho      72:     const double KILO_UNIT = 1024.0;
        !            73:     const double MEGA_UNIT = 1024.0 * 1024.0;
        !            74:     const double GIGA_UNIT = 1024.0 * 1024.0 * 1024.0;
        !            75:     const double TERA_UNIT = 1024.0 * 1024.0 * 1024.0 * 1024.0;
        !            76: 
        !            77:     const double KILO_RATE_UNIT = 1000.0;
        !            78:     const double MEGA_RATE_UNIT = 1000.0 * 1000.0;
        !            79:     const double GIGA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0;
        !            80:     const double TERA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0 * 1000.0;
1.1       misho      81: 
                     82: /* -------------------------------------------------------------------
                     83:  * unit_atof
                     84:  *
                     85:  * Given a string of form #x where # is a number and x is a format
                     86:  * character listed below, this returns the interpreted integer.
                     87:  * Gg, Mm, Kk are giga, mega, kilo respectively
                     88:  * ------------------------------------------------------------------- */
                     89: 
                     90:     double    unit_atof(const char *s)
                     91:     {
                     92:        double    n;
                     93:        char      suffix = '\0';
                     94: 
                     95:                  assert(s != NULL);
                     96: 
                     97:        /* scan the number and any suffices */
                     98:                  sscanf(s, "%lf%c", &n, &suffix);
                     99: 
1.1.1.2 ! misho     100:        /* convert according to [Tt Gg Mm Kk] */
1.1       misho     101:        switch    (suffix)
                    102:        {
1.1.1.2 ! misho     103:        case 't': case 'T':
        !           104:            n *= TERA_UNIT;
        !           105:            break;
1.1       misho     106:        case 'g': case 'G':
                    107:            n *= GIGA_UNIT;
                    108:            break;
                    109:        case 'm': case 'M':
                    110:            n *= MEGA_UNIT;
                    111:            break;
                    112:        case 'k': case 'K':
                    113:            n *= KILO_UNIT;
                    114:            break;
                    115:        default:
                    116:            break;
                    117:        }
                    118:                  return n;
                    119:     }                          /* end unit_atof */
                    120: 
                    121: 
                    122: /* -------------------------------------------------------------------
                    123:  * unit_atof_rate
                    124:  *
                    125:  * Similar to unit_atof, but uses 10-based rather than 2-based
                    126:  * suffixes.
                    127:  * ------------------------------------------------------------------- */
                    128: 
                    129:     double    unit_atof_rate(const char *s)
                    130:     {
                    131:        double    n;
                    132:        char      suffix = '\0';
                    133: 
                    134:                  assert(s != NULL);
                    135: 
                    136:        /* scan the number and any suffices */
                    137:                  sscanf(s, "%lf%c", &n, &suffix);
                    138: 
1.1.1.2 ! misho     139:        /* convert according to [Tt Gg Mm Kk] */
1.1       misho     140:        switch    (suffix)
                    141:        {
1.1.1.2 ! misho     142:        case 't': case 'T':
        !           143:            n *= TERA_RATE_UNIT;
        !           144:            break;
1.1       misho     145:        case 'g': case 'G':
                    146:            n *= GIGA_RATE_UNIT;
                    147:            break;
                    148:        case 'm': case 'M':
                    149:            n *= MEGA_RATE_UNIT;
                    150:            break;
                    151:        case 'k': case 'K':
                    152:            n *= KILO_RATE_UNIT;
                    153:            break;
                    154:        default:
                    155:            break;
                    156:        }
                    157:                  return n;
                    158:     }                          /* end unit_atof_rate */
                    159: 
                    160: 
                    161: 
                    162: /* -------------------------------------------------------------------
                    163:  * unit_atoi
                    164:  *
                    165:  * Given a string of form #x where # is a number and x is a format
                    166:  * character listed below, this returns the interpreted integer.
1.1.1.2 ! misho     167:  * Tt, Gg, Mm, Kk are tera, giga, mega, kilo respectively
1.1       misho     168:  * ------------------------------------------------------------------- */
                    169: 
                    170:     iperf_size_t unit_atoi(const char *s)
                    171:     {
                    172:        double    n;
                    173:        char      suffix = '\0';
                    174: 
                    175:                  assert(s != NULL);
                    176: 
                    177:        /* scan the number and any suffices */
                    178:                  sscanf(s, "%lf%c", &n, &suffix);
                    179: 
1.1.1.2 ! misho     180:        /* convert according to [Tt Gg Mm Kk] */
1.1       misho     181:        switch    (suffix)
                    182:        {
1.1.1.2 ! misho     183:        case 't': case 'T':
        !           184:            n *= TERA_UNIT;
        !           185:            break;
1.1       misho     186:        case 'g': case 'G':
                    187:            n *= GIGA_UNIT;
                    188:            break;
                    189:        case 'm': case 'M':
                    190:            n *= MEGA_UNIT;
                    191:            break;
                    192:        case 'k': case 'K':
                    193:            n *= KILO_UNIT;
                    194:            break;
                    195:        default:
                    196:            break;
                    197:        }
                    198:                  return (iperf_size_t) n;
                    199:     }                          /* end unit_atof */
                    200: 
                    201: /* -------------------------------------------------------------------
                    202:  * constants for byte_printf
                    203:  * ------------------------------------------------------------------- */
                    204: 
                    205: /* used as indices into conversion_bytes[], label_byte[], and label_bit[] */
                    206:     enum
                    207:     {
                    208:        UNIT_CONV,
                    209:        KILO_CONV,
                    210:        MEGA_CONV,
1.1.1.2 ! misho     211:        GIGA_CONV,
        !           212:        TERA_CONV
1.1       misho     213:     };
                    214: 
                    215: /* factor to multiply the number by */
                    216:     const double conversion_bytes[] =
                    217:     {
                    218:        1.0,                    /* unit */
                    219:        1.0 / 1024,             /* kilo */
                    220:        1.0 / 1024 / 1024,      /* mega */
1.1.1.2 ! misho     221:        1.0 / 1024 / 1024 / 1024, /* giga */
        !           222:        1.0 / 1024 / 1024 / 1024 / 1024 /* tera */
1.1       misho     223:     };
                    224: 
                    225: /* factor to multiply the number by for bits*/
                    226:     const double conversion_bits[] =
                    227:     {
                    228:        1.0,                    /* unit */
                    229:        1.0 / 1000,             /* kilo */
                    230:        1.0 / 1000 / 1000,      /* mega */
1.1.1.2 ! misho     231:        1.0 / 1000 / 1000 / 1000, /* giga */
        !           232:        1.0 / 1000 / 1000 / 1000 / 1000 /* tera */
1.1       misho     233:     };
                    234: 
                    235: 
1.1.1.2 ! misho     236: /* labels for Byte formats [KMGT] */
1.1       misho     237:     const char *label_byte[] =
                    238:     {
                    239:        "Byte",
                    240:        "KByte",
                    241:        "MByte",
1.1.1.2 ! misho     242:        "GByte",
        !           243:        "TByte"
1.1       misho     244:     };
                    245: 
1.1.1.2 ! misho     246: /* labels for bit formats [kmgt] */
1.1       misho     247:     const char *label_bit[] =
                    248:     {
                    249:        "bit",
                    250:        "Kbit",
                    251:        "Mbit",
1.1.1.2 ! misho     252:        "Gbit",
        !           253:        "Tbit"
1.1       misho     254:     };
                    255: 
                    256: /* -------------------------------------------------------------------
                    257:  * unit_snprintf
                    258:  *
                    259:  * Given a number in bytes and a format, converts the number and
                    260:  * prints it out with a bits or bytes label.
                    261:  *   B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte
                    262:  *   b, k, m, g, a for bit,  Kbit,  Mbit,  Gbit,  adaptive bit
                    263:  * adaptive picks the "best" one based on the number.
                    264:  * s should be at least 11 chars long
                    265:  * (4 digits + space + 5 chars max + null)
                    266:  * ------------------------------------------------------------------- */
                    267: 
                    268:     void      unit_snprintf(char *s, int inLen,
                    269:                                      double inNum, char inFormat)
                    270:     {
                    271:        int       conv;
                    272:        const char *suffix;
                    273:        const char *format;
                    274: 
                    275:        /* convert to bits for [bkmga] */
                    276:        if        (!isupper((int) inFormat))
                    277:        {
                    278:            inNum *= 8;
                    279:        }
                    280:        switch    (toupper((u_char)inFormat))
                    281:        {
                    282:        case 'B':
                    283:            conv = UNIT_CONV;
                    284:            break;
                    285:        case 'K':
                    286:            conv = KILO_CONV;
                    287:            break;
                    288:        case 'M':
                    289:            conv = MEGA_CONV;
                    290:            break;
                    291:        case 'G':
                    292:            conv = GIGA_CONV;
                    293:            break;
1.1.1.2 ! misho     294:        case 'T':
        !           295:            conv = TERA_CONV;
        !           296:            break;
1.1       misho     297: 
                    298:        default:
                    299:        case 'A':
                    300:            {
                    301:                double    tmpNum = inNum;
                    302:                conv = UNIT_CONV;
                    303: 
                    304:                if (isupper((int) inFormat))
                    305:                {
1.1.1.2 ! misho     306:                    while (tmpNum >= 1024.0 && conv < TERA_CONV)
1.1       misho     307:                    {
                    308:                        tmpNum /= 1024.0;
                    309:                        conv++;
                    310:                    }
                    311:                } else
                    312:                {
1.1.1.2 ! misho     313:                    while (tmpNum >= 1000.0 && conv < TERA_CONV)
1.1       misho     314:                    {
                    315:                        tmpNum /= 1000.0;
                    316:                        conv++;
                    317:                    }
                    318:                }
                    319:                break;
                    320:            }
                    321:        }
                    322: 
                    323:        if (!isupper((int) inFormat))
                    324:        {
                    325:            inNum *= conversion_bits[conv];
                    326:            suffix = label_bit[conv];
                    327:        } else
                    328:        {
                    329:            inNum *= conversion_bytes[conv];
                    330:            suffix = label_byte[conv];
                    331:        }
                    332: 
                    333:        /* print such that we always fit in 4 places */
                    334:        if (inNum < 9.995)
                    335:        {                       /* 9.995 would be rounded to 10.0 */
                    336:            format = "%4.2f %s";/* #.## */
                    337:        } else if (inNum < 99.95)
                    338:        {                       /* 99.95 would be rounded to 100 */
                    339:            format = "%4.1f %s";/* ##.# */
                    340:        } else if (inNum < 999.5)
                    341:        {                       /* 999.5 would be rounded to 1000 */
                    342:            format = "%4.0f %s";/* ### */
                    343:        } else
                    344:        {                       /* 1000-1024 fits in 4 places If not using
                    345:                                 * Adaptive sizes then this code will not
                    346:                                 * control spaces */
                    347:            format = "%4.0f %s";/* #### */
                    348:        }
                    349:        snprintf(s, inLen, format, inNum, suffix);
                    350:     }                          /* end unit_snprintf */
                    351: 
                    352: #ifdef __cplusplus
                    353: }                              /* end extern "C" */
                    354: 
                    355: #endif

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