convert.py revision 1858
1# Copyright (c) 2005 The Regents of The University of Michigan
2# All rights reserved.
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions are
6# met: redistributions of source code must retain the above copyright
7# notice, this list of conditions and the following disclaimer;
8# redistributions in binary form must reproduce the above copyright
9# notice, this list of conditions and the following disclaimer in the
10# documentation and/or other materials provided with the distribution;
11# neither the name of the copyright holders nor the names of its
12# contributors may be used to endorse or promote products derived from
13# this software without specific prior written permission.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27# metric prefixes
28exa  = 1.0e18
29peta = 1.0e15
30tera = 1.0e12
31giga = 1.0e9
32mega = 1.0e6
33kilo = 1.0e3
34
35milli = 1.0e-3
36micro = 1.0e-6
37nano  = 1.0e-9
38pico  = 1.0e-12
39femto = 1.0e-15
40atto  = 1.0e-18
41
42# power of 2 prefixes
43kibi = 1024
44mebi = kibi * 1024
45gibi = mebi * 1024
46tebi = gibi * 1024
47pebi = tebi * 1024
48exbi = pebi * 1024
49
50# memory size configuration stuff
51def toFloat(value):
52    if not isinstance(value, str):
53        raise TypeError, "wrong type '%s' should be str" % type(value)
54
55    if value.endswith('Ei'):
56        return float(value[:-2]) * exbi
57    elif value.endswith('Pi'):
58        return float(value[:-2]) * pebi
59    elif value.endswith('Ti'):
60        return float(value[:-2]) * tebi
61    elif value.endswith('Gi'):
62        return float(value[:-2]) * gibi
63    elif value.endswith('Mi'):
64        return float(value[:-2]) * mebi
65    elif value.endswith('ki'):
66        return float(value[:-2]) * kibi
67    elif value.endswith('E'):
68        return float(value[:-1]) * exa
69    elif value.endswith('P'):
70        return float(value[:-1]) * peta
71    elif value.endswith('T'):
72        return float(value[:-1]) * tera
73    elif value.endswith('G'):
74        return float(value[:-1]) * giga
75    elif value.endswith('M'):
76        return float(value[:-1]) * mega
77    elif value.endswith('k'):
78        return float(value[:-1]) * kilo
79    elif value.endswith('m'):
80        return float(value[:-1]) * milli
81    elif value.endswith('u'):
82        return float(value[:-1]) * micro
83    elif value.endswith('n'):
84        return float(value[:-1]) * nano
85    elif value.endswith('p'):
86        return float(value[:-1]) * pico
87    elif value.endswith('f'):
88        return float(value[:-1]) * femto
89    else:
90        return float(value)
91
92def toLong(value):
93    value = toFloat(value)
94    result = int(value)
95    if value != result:
96        raise ValueError, "cannot convert '%s' to long" % value
97
98    return result
99
100def toInteger(value):
101    value = toFloat(value)
102    result = int(value)
103    if value != result:
104        raise ValueError, "cannot convert '%s' to integer" % value
105
106    return result
107
108_bool_dict = {
109    'true' : True,   't' : True,  'yes' : True, 'y' : True,  '1' : True,
110    'false' : False, 'f' : False, 'no' : False, 'n' : False, '0' : False
111    }
112
113def toBool(value):
114    if not isinstance(value, str):
115        raise TypeError, "wrong type '%s' should be str" % type(value)
116
117    value = value.lower()
118    result = _bool_dict.get(value, None)
119    if result == None:
120        raise ValueError, "cannot convert '%s' to bool" % value
121    return result
122
123def toFrequency(value):
124    if not isinstance(value, str):
125        raise TypeError, "wrong type '%s' should be str" % type(value)
126
127    if value.endswith('THz'):
128        return float(value[:-3]) * tera
129    elif value.endswith('GHz'):
130        return float(value[:-3]) * giga
131    elif value.endswith('MHz'):
132        return float(value[:-3]) * mega
133    elif value.endswith('kHz'):
134        return float(value[:-3]) * kilo
135    elif value.endswith('Hz'):
136        return float(value[:-2])
137
138    raise ValueError, "cannot convert '%s' to frequency" % value
139
140def toLatency(value):
141    if not isinstance(value, str):
142        raise TypeError, "wrong type '%s' should be str" % type(value)
143
144    if value.endswith('ps'):
145        return float(value[:-2]) * pico
146    elif value.endswith('ns'):
147        return float(value[:-2]) * nano
148    elif value.endswith('us'):
149        return float(value[:-2]) * micro
150    elif value.endswith('ms'):
151        return float(value[:-2]) * milli
152    elif value.endswith('s'):
153        return float(value[:-1])
154
155    raise ValueError, "cannot convert '%s' to latency" % value
156
157def toClockPeriod(value):
158    """result is a clock period"""
159
160    if not isinstance(value, str):
161        raise TypeError, "wrong type '%s' should be str" % type(value)
162
163    try:
164        val = toFrequency(value)
165        if val != 0:
166            val = 1 / val
167        return val
168    except ValueError:
169        pass
170
171    try:
172        val = toLatency(value)
173        return val
174    except ValueError:
175        pass
176
177    raise ValueError, "cannot convert '%s' to clock period" % value
178
179
180def toNetworkBandwidth(value):
181    if not isinstance(value, str):
182        raise TypeError, "wrong type '%s' should be str" % type(value)
183
184    if value.endswith('Tbps'):
185        return float(value[:-4]) * tera
186    elif value.endswith('Gbps'):
187        return float(value[:-4]) * giga
188    elif value.endswith('Mbps'):
189        return float(value[:-4]) * mega
190    elif value.endswith('kbps'):
191        return float(value[:-4]) * kilo
192    elif value.endswith('bps'):
193        return float(value[:-3])
194    else:
195        return float(value)
196
197    raise ValueError, "cannot convert '%s' to network bandwidth" % value
198
199def toMemoryBandwidth(value):
200    if not isinstance(value, str):
201        raise TypeError, "wrong type '%s' should be str" % type(value)
202
203    if value.endswith('PB/s'):
204        return float(value[:-4]) * pebi
205    elif value.endswith('TB/s'):
206        return float(value[:-4]) * tebi
207    elif value.endswith('GB/s'):
208        return float(value[:-4]) * gibi
209    elif value.endswith('MB/s'):
210        return float(value[:-4]) * mebi
211    elif value.endswith('kB/s'):
212        return float(value[:-4]) * kibi
213    elif value.endswith('B/s'):
214        return float(value[:-3])
215
216    raise ValueError, "cannot convert '%s' to memory bandwidth" % value
217
218def toMemorySize(value):
219    if not isinstance(value, str):
220        raise TypeError, "wrong type '%s' should be str" % type(value)
221
222    if value.endswith('PB'):
223        return float(value[:-2]) * pebi
224    elif value.endswith('TB'):
225        return float(value[:-2]) * tebi
226    elif value.endswith('GB'):
227        return float(value[:-2]) * gibi
228    elif value.endswith('MB'):
229        return float(value[:-2]) * mebi
230    elif value.endswith('kB'):
231        return float(value[:-2]) * kibi
232    elif value.endswith('B'):
233        return float(value[:-1])
234
235    raise ValueError, "cannot convert '%s' to memory size" % value
236