diff options
author | Haibo Huang <hhb@google.com> | 2019-03-29 10:09:21 -0700 |
---|---|---|
committer | Haibo Huang <hhb@google.com> | 2019-03-29 17:35:06 +0000 |
commit | 87ad254d23c8cbcb56c3b69928bca97c3d49b0a6 (patch) | |
tree | b051820819acd041667fed788704f5022552c7c1 /src/units.c | |
parent | b9d45f84cb4ee9997a25291a8da76b278de2c525 (diff) | |
parent | 40e7c05440583f229edd6b6ca05c5d97b66fcf15 (diff) | |
download | iperf3-87ad254d23c8cbcb56c3b69928bca97c3d49b0a6.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into master
Also adds NOTICE, METADATA, MODULE_LICENSE_*
Test: NA (not build yet)
Change-Id: Ia08a651fdecc5e540c2cad218a128099c7322280
Diffstat (limited to 'src/units.c')
-rw-r--r-- | src/units.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/units.c b/src/units.c new file mode 100644 index 0000000..7376a0b --- /dev/null +++ b/src/units.c @@ -0,0 +1,355 @@ +/*--------------------------------------------------------------- + * Copyright (c) 1999,2000,2001,2002,2003 + * The Board of Trustees of the University of Illinois + * All Rights Reserved. + *--------------------------------------------------------------- + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software (Iperf) and associated + * documentation files (the "Software"), to deal in the Software + * without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit + * persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and + * the following disclaimers. + * + * + * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimers in the documentation and/or other materials + * provided with the distribution. + * + * + * Neither the names of the University of Illinois, NCSA, + * nor the names of its contributors may be used to endorse + * or promote products derived from this Software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE CONTIBUTORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * ________________________________________________________________ + * National Laboratory for Applied Network Research + * National Center for Supercomputing Applications + * University of Illinois at Urbana-Champaign + * http://www.ncsa.uiuc.edu + * ________________________________________________________________ + * + * stdio.c + * by Mark Gates <mgates@nlanr.net> + * and Ajay Tirumalla <tirumala@ncsa.uiuc.edu> + * ------------------------------------------------------------------- + * input and output numbers, converting with kilo, mega, giga, tera + * ------------------------------------------------------------------- */ + +#include <stdio.h> +#include <assert.h> +#include <ctype.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/time.h> + + +#include "iperf.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + const double KILO_UNIT = 1024.0; + const double MEGA_UNIT = 1024.0 * 1024.0; + const double GIGA_UNIT = 1024.0 * 1024.0 * 1024.0; + const double TERA_UNIT = 1024.0 * 1024.0 * 1024.0 * 1024.0; + + const double KILO_RATE_UNIT = 1000.0; + const double MEGA_RATE_UNIT = 1000.0 * 1000.0; + const double GIGA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0; + const double TERA_RATE_UNIT = 1000.0 * 1000.0 * 1000.0 * 1000.0; + +/* ------------------------------------------------------------------- + * unit_atof + * + * Given a string of form #x where # is a number and x is a format + * character listed below, this returns the interpreted integer. + * Gg, Mm, Kk are giga, mega, kilo respectively + * ------------------------------------------------------------------- */ + + double unit_atof(const char *s) + { + double n; + char suffix = '\0'; + + assert(s != NULL); + + /* scan the number and any suffices */ + sscanf(s, "%lf%c", &n, &suffix); + + /* convert according to [Tt Gg Mm Kk] */ + switch (suffix) + { + case 't': case 'T': + n *= TERA_UNIT; + break; + case 'g': case 'G': + n *= GIGA_UNIT; + break; + case 'm': case 'M': + n *= MEGA_UNIT; + break; + case 'k': case 'K': + n *= KILO_UNIT; + break; + default: + break; + } + return n; + } /* end unit_atof */ + + +/* ------------------------------------------------------------------- + * unit_atof_rate + * + * Similar to unit_atof, but uses 10-based rather than 2-based + * suffixes. + * ------------------------------------------------------------------- */ + + double unit_atof_rate(const char *s) + { + double n; + char suffix = '\0'; + + assert(s != NULL); + + /* scan the number and any suffices */ + sscanf(s, "%lf%c", &n, &suffix); + + /* convert according to [Tt Gg Mm Kk] */ + switch (suffix) + { + case 't': case 'T': + n *= TERA_RATE_UNIT; + break; + case 'g': case 'G': + n *= GIGA_RATE_UNIT; + break; + case 'm': case 'M': + n *= MEGA_RATE_UNIT; + break; + case 'k': case 'K': + n *= KILO_RATE_UNIT; + break; + default: + break; + } + return n; + } /* end unit_atof_rate */ + + + +/* ------------------------------------------------------------------- + * unit_atoi + * + * Given a string of form #x where # is a number and x is a format + * character listed below, this returns the interpreted integer. + * Tt, Gg, Mm, Kk are tera, giga, mega, kilo respectively + * ------------------------------------------------------------------- */ + + iperf_size_t unit_atoi(const char *s) + { + double n; + char suffix = '\0'; + + assert(s != NULL); + + /* scan the number and any suffices */ + sscanf(s, "%lf%c", &n, &suffix); + + /* convert according to [Tt Gg Mm Kk] */ + switch (suffix) + { + case 't': case 'T': + n *= TERA_UNIT; + break; + case 'g': case 'G': + n *= GIGA_UNIT; + break; + case 'm': case 'M': + n *= MEGA_UNIT; + break; + case 'k': case 'K': + n *= KILO_UNIT; + break; + default: + break; + } + return (iperf_size_t) n; + } /* end unit_atof */ + +/* ------------------------------------------------------------------- + * constants for byte_printf + * ------------------------------------------------------------------- */ + +/* used as indices into conversion_bytes[], label_byte[], and label_bit[] */ + enum + { + UNIT_CONV, + KILO_CONV, + MEGA_CONV, + GIGA_CONV, + TERA_CONV + }; + +/* factor to multiply the number by */ + const double conversion_bytes[] = + { + 1.0, /* unit */ + 1.0 / 1024, /* kilo */ + 1.0 / 1024 / 1024, /* mega */ + 1.0 / 1024 / 1024 / 1024, /* giga */ + 1.0 / 1024 / 1024 / 1024 / 1024 /* tera */ + }; + +/* factor to multiply the number by for bits*/ + const double conversion_bits[] = + { + 1.0, /* unit */ + 1.0 / 1000, /* kilo */ + 1.0 / 1000 / 1000, /* mega */ + 1.0 / 1000 / 1000 / 1000, /* giga */ + 1.0 / 1000 / 1000 / 1000 / 1000 /* tera */ + }; + + +/* labels for Byte formats [KMGT] */ + const char *label_byte[] = + { + "Byte", + "KByte", + "MByte", + "GByte", + "TByte" + }; + +/* labels for bit formats [kmgt] */ + const char *label_bit[] = + { + "bit", + "Kbit", + "Mbit", + "Gbit", + "Tbit" + }; + +/* ------------------------------------------------------------------- + * unit_snprintf + * + * Given a number in bytes and a format, converts the number and + * prints it out with a bits or bytes label. + * B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte + * b, k, m, g, a for bit, Kbit, Mbit, Gbit, adaptive bit + * adaptive picks the "best" one based on the number. + * s should be at least 11 chars long + * (4 digits + space + 5 chars max + null) + * ------------------------------------------------------------------- */ + + void unit_snprintf(char *s, int inLen, + double inNum, char inFormat) + { + int conv; + const char *suffix; + const char *format; + + /* convert to bits for [bkmga] */ + if (!isupper((int) inFormat)) + { + inNum *= 8; + } + switch (toupper((u_char)inFormat)) + { + case 'B': + conv = UNIT_CONV; + break; + case 'K': + conv = KILO_CONV; + break; + case 'M': + conv = MEGA_CONV; + break; + case 'G': + conv = GIGA_CONV; + break; + case 'T': + conv = TERA_CONV; + break; + + default: + case 'A': + { + double tmpNum = inNum; + conv = UNIT_CONV; + + if (isupper((int) inFormat)) + { + while (tmpNum >= 1024.0 && conv < TERA_CONV) + { + tmpNum /= 1024.0; + conv++; + } + } else + { + while (tmpNum >= 1000.0 && conv < TERA_CONV) + { + tmpNum /= 1000.0; + conv++; + } + } + break; + } + } + + if (!isupper((int) inFormat)) + { + inNum *= conversion_bits[conv]; + suffix = label_bit[conv]; + } else + { + inNum *= conversion_bytes[conv]; + suffix = label_byte[conv]; + } + + /* print such that we always fit in 4 places */ + if (inNum < 9.995) + { /* 9.995 would be rounded to 10.0 */ + format = "%4.2f %s";/* #.## */ + } else if (inNum < 99.95) + { /* 99.95 would be rounded to 100 */ + format = "%4.1f %s";/* ##.# */ + } else if (inNum < 999.5) + { /* 999.5 would be rounded to 1000 */ + format = "%4.0f %s";/* ### */ + } else + { /* 1000-1024 fits in 4 places If not using + * Adaptive sizes then this code will not + * control spaces */ + format = "%4.0f %s";/* #### */ + } + snprintf(s, inLen, format, inNum, suffix); + } /* end unit_snprintf */ + +#ifdef __cplusplus +} /* end extern "C" */ + +#endif |