aboutsummaryrefslogtreecommitdiff
path: root/src/units.c
diff options
context:
space:
mode:
authorHaibo Huang <hhb@google.com>2019-03-29 10:09:21 -0700
committerHaibo Huang <hhb@google.com>2019-03-29 17:35:06 +0000
commit87ad254d23c8cbcb56c3b69928bca97c3d49b0a6 (patch)
treeb051820819acd041667fed788704f5022552c7c1 /src/units.c
parentb9d45f84cb4ee9997a25291a8da76b278de2c525 (diff)
parent40e7c05440583f229edd6b6ca05c5d97b66fcf15 (diff)
downloadiperf3-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.c355
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