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>