]> sjero.net Git - iperf/blob - src/stdio.c
DCCP support for iperf
[iperf] / src / stdio.c
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 "headers.h"
55 #include "util.h"
56
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
60
61 const long kKilo_to_Unit = 1024;
62 const long kMega_to_Unit = 1024 * 1024;
63 const long kGiga_to_Unit = 1024 * 1024 * 1024;
64
65 const long kkilo_to_Unit = 1000;
66 const long kmega_to_Unit = 1000 * 1000;
67 const long kgiga_to_Unit = 1000 * 1000 * 1000;
68
69 /* -------------------------------------------------------------------
70  * byte_atof
71  *
72  * Given a string of form #x where # is a number and x is a format
73  * character listed below, this returns the interpreted integer.
74  * Gg, Mm, Kk are giga, mega, kilo respectively
75  * ------------------------------------------------------------------- */
76
77 double byte_atof( const char *inString ) {
78     double theNum;
79     char suffix = '\0';
80
81     assert( inString != NULL );
82
83     /* scan the number and any suffices */
84     sscanf( inString, "%lf%c", &theNum, &suffix );
85
86     /* convert according to [Gg Mm Kk] */
87     switch ( suffix ) {
88         case 'G':  theNum *= kGiga_to_Unit;  break;
89         case 'M':  theNum *= kMega_to_Unit;  break;
90         case 'K':  theNum *= kKilo_to_Unit;  break;
91         case 'g':  theNum *= kgiga_to_Unit;  break;
92         case 'm':  theNum *= kmega_to_Unit;  break;
93         case 'k':  theNum *= kkilo_to_Unit;  break;
94         default: break;
95     }
96     return theNum;
97 } /* end byte_atof */
98
99 /* -------------------------------------------------------------------
100  * byte_atoi
101  *
102  * Given a string of form #x where # is a number and x is a format
103  * character listed below, this returns the interpreted integer.
104  * Gg, Mm, Kk are giga, mega, kilo respectively
105  * ------------------------------------------------------------------- */
106
107 max_size_t byte_atoi( const char *inString ) {
108     double theNum;
109     char suffix = '\0';
110
111     assert( inString != NULL );
112
113     /* scan the number and any suffices */
114     sscanf( inString, "%lf%c", &theNum, &suffix );
115
116     /* convert according to [Gg Mm Kk] */
117     switch ( suffix ) {
118         case 'G':  theNum *= kGiga_to_Unit;  break;
119         case 'M':  theNum *= kMega_to_Unit;  break;
120         case 'K':  theNum *= kKilo_to_Unit;  break;
121         case 'g':  theNum *= kgiga_to_Unit;  break;
122         case 'm':  theNum *= kmega_to_Unit;  break;
123         case 'k':  theNum *= kkilo_to_Unit;  break;
124         default: break;
125     }
126     return (max_size_t) theNum;
127 } /* end byte_atof */
128
129 /* -------------------------------------------------------------------
130  * constants for byte_printf
131  * ------------------------------------------------------------------- */
132
133 /* used as indices into kConversion[], kLabel_Byte[], and kLabel_bit[] */
134 enum {
135     kConv_Unit,
136     kConv_Kilo,
137     kConv_Mega,
138     kConv_Giga
139 };
140
141 /* factor to multiply the number by */
142 const double kConversion[] =
143 {
144     1.0,                       /* unit */
145     1.0 / 1024,                /* kilo */
146     1.0 / 1024 / 1024,         /* mega */
147     1.0 / 1024 / 1024 / 1024   /* giga */
148 };
149
150 /* factor to multiply the number by for bits*/
151 const double kConversionForBits[] =
152 {
153     1.0,                       /* unit */
154     1.0 / 1000,                /* kilo */
155     1.0 / 1000 / 1000,         /* mega */
156     1.0 / 1000 / 1000 / 1000   /* giga */
157 };
158
159
160 /* labels for Byte formats [KMG] */
161 const char* kLabel_Byte[] =
162 {
163     "Byte",
164     "KByte",
165     "MByte",
166     "GByte"
167 };
168
169 /* labels for bit formats [kmg] */
170 const char* kLabel_bit[]  =
171 {
172     "bit", 
173     "Kbit",
174     "Mbit",
175     "Gbit"
176 };
177
178 /* -------------------------------------------------------------------
179  * byte_snprintf
180  *
181  * Given a number in bytes and a format, converts the number and
182  * prints it out with a bits or bytes label.
183  *   B, K, M, G, A for Byte, Kbyte, Mbyte, Gbyte, adaptive byte
184  *   b, k, m, g, a for bit,  Kbit,  Mbit,  Gbit,  adaptive bit
185  * adaptive picks the "best" one based on the number.
186  * outString should be at least 11 chars long
187  * (4 digits + space + 5 chars max + null)
188  * ------------------------------------------------------------------- */
189
190 void byte_snprintf( char* outString, int inLen,
191                     double inNum, char inFormat ) {
192     int conv;
193     const char* suffix;
194     const char* format;
195
196     /* convert to bits for [bkmga] */
197     if ( ! isupper( (int)inFormat ) ) {
198         inNum *= 8;
199     }
200
201     switch ( toupper(inFormat) ) {
202         case 'B': conv = kConv_Unit; break;
203         case 'K': conv = kConv_Kilo; break;
204         case 'M': conv = kConv_Mega; break;
205         case 'G': conv = kConv_Giga; break;
206
207         default:
208         case 'A': {
209                 double tmpNum = inNum;
210                 conv = kConv_Unit;
211
212                 if ( isupper((int)inFormat) ) {
213                     while ( tmpNum >= 1024.0  &&  conv <= kConv_Giga ) {
214                         tmpNum /= 1024.0;
215                         conv++;
216                     }
217                 } else {
218                     while ( tmpNum >= 1000.0  &&  conv <= kConv_Giga ) {
219                         tmpNum /= 1000.0;
220                         conv++;
221                     }
222                 }
223                 break;
224             }
225     }
226
227     if ( ! isupper ((int)inFormat) ) {
228         inNum *= kConversionForBits[ conv ];
229         suffix = kLabel_bit[conv];
230     } else {
231         inNum *= kConversion [conv];
232         suffix = kLabel_Byte[ conv ];
233     }
234
235     /* print such that we always fit in 4 places */
236     if ( inNum < 9.995 ) {          /* 9.995 would be rounded to 10.0 */
237         format = "%4.2f %s";        /* #.## */
238     } else if ( inNum < 99.95 ) {   /* 99.95 would be rounded to 100 */
239         format = "%4.1f %s";        /* ##.# */
240     } else if ( inNum < 999.5 ) {   /* 999.5 would be rounded to 1000 */
241         format = "%4.0f %s";        /*  ### */
242     } else {                        /* 1000-1024 fits in 4 places 
243                                      * If not using Adaptive sizes then
244                                      * this code will not control spaces*/
245         format = "%4.0f %s";        /* #### */
246     }
247     snprintf( outString, inLen, format, inNum, suffix );
248 } /* end byte_snprintf */
249
250 /* -------------------------------------------------------------------
251  * redirect
252  *
253  * redirect the stdout into a specified file
254  * return: none
255  * ------------------------------------------------------------------- */
256
257 void redirect(const char *inOutputFileName)
258 {
259     return;
260 }
261
262
263 #ifdef __cplusplus
264 } /* end extern "C" */
265 #endif
266