convert.py revision 7777
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# Authors: Nathan Binkert 28 29# metric prefixes 30exa = 1.0e18 31peta = 1.0e15 32tera = 1.0e12 33giga = 1.0e9 34mega = 1.0e6 35kilo = 1.0e3 36 37milli = 1.0e-3 38micro = 1.0e-6 39nano = 1.0e-9 40pico = 1.0e-12 41femto = 1.0e-15 42atto = 1.0e-18 43 44# power of 2 prefixes 45kibi = 1024 46mebi = kibi * 1024 47gibi = mebi * 1024 48tebi = gibi * 1024 49pebi = tebi * 1024 50exbi = pebi * 1024 51 52# memory size configuration stuff 53def toFloat(value): 54 if not isinstance(value, str): 55 raise TypeError, "wrong type '%s' should be str" % type(value) 56 57 if value.endswith('Ei'): 58 return float(value[:-2]) * exbi 59 elif value.endswith('Pi'): 60 return float(value[:-2]) * pebi 61 elif value.endswith('Ti'): 62 return float(value[:-2]) * tebi 63 elif value.endswith('Gi'): 64 return float(value[:-2]) * gibi 65 elif value.endswith('Mi'): 66 return float(value[:-2]) * mebi 67 elif value.endswith('ki'): 68 return float(value[:-2]) * kibi 69 elif value.endswith('E'): 70 return float(value[:-1]) * exa 71 elif value.endswith('P'): 72 return float(value[:-1]) * peta 73 elif value.endswith('T'): 74 return float(value[:-1]) * tera 75 elif value.endswith('G'): 76 return float(value[:-1]) * giga 77 elif value.endswith('M'): 78 return float(value[:-1]) * mega 79 elif value.endswith('k'): 80 return float(value[:-1]) * kilo 81 elif value.endswith('m'): 82 return float(value[:-1]) * milli 83 elif value.endswith('u'): 84 return float(value[:-1]) * micro 85 elif value.endswith('n'): 86 return float(value[:-1]) * nano 87 elif value.endswith('p'): 88 return float(value[:-1]) * pico 89 elif value.endswith('f'): 90 return float(value[:-1]) * femto 91 else: 92 return float(value) 93 94def toInteger(value): 95 value = toFloat(value) 96 result = long(value) 97 if value != result: 98 raise ValueError, "cannot convert '%s' to integer" % value 99 100 return result 101 102_bool_dict = { 103 'true' : True, 't' : True, 'yes' : True, 'y' : True, '1' : True, 104 'false' : False, 'f' : False, 'no' : False, 'n' : False, '0' : False 105 } 106 107def toBool(value): 108 if not isinstance(value, str): 109 raise TypeError, "wrong type '%s' should be str" % type(value) 110 111 value = value.lower() 112 result = _bool_dict.get(value, None) 113 if result == None: 114 raise ValueError, "cannot convert '%s' to bool" % value 115 return result 116 117def toFrequency(value): 118 if not isinstance(value, str): 119 raise TypeError, "wrong type '%s' should be str" % type(value) 120 121 if value.endswith('THz'): 122 return float(value[:-3]) * tera 123 elif value.endswith('GHz'): 124 return float(value[:-3]) * giga 125 elif value.endswith('MHz'): 126 return float(value[:-3]) * mega 127 elif value.endswith('kHz'): 128 return float(value[:-3]) * kilo 129 elif value.endswith('Hz'): 130 return float(value[:-2]) 131 132 raise ValueError, "cannot convert '%s' to frequency" % value 133 134def toLatency(value): 135 if not isinstance(value, str): 136 raise TypeError, "wrong type '%s' should be str" % type(value) 137 138 if value.endswith('ps'): 139 return float(value[:-2]) * pico 140 elif value.endswith('ns'): 141 return float(value[:-2]) * nano 142 elif value.endswith('us'): 143 return float(value[:-2]) * micro 144 elif value.endswith('ms'): 145 return float(value[:-2]) * milli 146 elif value.endswith('s'): 147 return float(value[:-1]) 148 149 raise ValueError, "cannot convert '%s' to latency" % value 150 151def anyToLatency(value): 152 """result is a clock period""" 153 154 if not isinstance(value, str): 155 raise TypeError, "wrong type '%s' should be str" % type(value) 156 157 try: 158 val = toFrequency(value) 159 if val != 0: 160 val = 1 / val 161 return val 162 except ValueError: 163 pass 164 165 try: 166 val = toLatency(value) 167 return val 168 except ValueError: 169 pass 170 171 raise ValueError, "cannot convert '%s' to clock period" % value 172 173def anyToFrequency(value): 174 """result is a clock period""" 175 176 if not isinstance(value, str): 177 raise TypeError, "wrong type '%s' should be str" % type(value) 178 179 try: 180 val = toFrequency(value) 181 return val 182 except ValueError: 183 pass 184 185 try: 186 val = toLatency(value) 187 if val != 0: 188 val = 1 / val 189 return val 190 except ValueError: 191 pass 192 193 raise ValueError, "cannot convert '%s' to clock period" % value 194 195def toNetworkBandwidth(value): 196 if not isinstance(value, str): 197 raise TypeError, "wrong type '%s' should be str" % type(value) 198 199 if value.endswith('Tbps'): 200 return float(value[:-4]) * tera 201 elif value.endswith('Gbps'): 202 return float(value[:-4]) * giga 203 elif value.endswith('Mbps'): 204 return float(value[:-4]) * mega 205 elif value.endswith('kbps'): 206 return float(value[:-4]) * kilo 207 elif value.endswith('bps'): 208 return float(value[:-3]) 209 else: 210 return float(value) 211 212 raise ValueError, "cannot convert '%s' to network bandwidth" % value 213 214def toMemoryBandwidth(value): 215 if not isinstance(value, str): 216 raise TypeError, "wrong type '%s' should be str" % type(value) 217 218 if value.endswith('PB/s'): 219 return float(value[:-4]) * pebi 220 elif value.endswith('TB/s'): 221 return float(value[:-4]) * tebi 222 elif value.endswith('GB/s'): 223 return float(value[:-4]) * gibi 224 elif value.endswith('MB/s'): 225 return float(value[:-4]) * mebi 226 elif value.endswith('kB/s'): 227 return float(value[:-4]) * kibi 228 elif value.endswith('B/s'): 229 return float(value[:-3]) 230 231 raise ValueError, "cannot convert '%s' to memory bandwidth" % value 232 233def toMemorySize(value): 234 if not isinstance(value, str): 235 raise TypeError, "wrong type '%s' should be str" % type(value) 236 237 if value.endswith('PB'): 238 return long(value[:-2]) * pebi 239 elif value.endswith('TB'): 240 return long(value[:-2]) * tebi 241 elif value.endswith('GB'): 242 return long(value[:-2]) * gibi 243 elif value.endswith('MB'): 244 return long(value[:-2]) * mebi 245 elif value.endswith('kB'): 246 return long(value[:-2]) * kibi 247 elif value.endswith('B'): 248 return long(value[:-1]) 249 250 raise ValueError, "cannot convert '%s' to memory size" % value 251 252def toIpAddress(value): 253 if not isinstance(value, str): 254 raise TypeError, "wrong type '%s' should be str" % type(value) 255 256 bytes = value.split('.') 257 if len(bytes) != 4: 258 raise ValueError, 'invalid ip address %s' % value 259 260 for byte in bytes: 261 if not 0 <= int(byte) <= 0xff: 262 raise ValueError, 'invalid ip address %s' % value 263 264 return (int(bytes[0]) << 24) | (int(bytes[1]) << 16) | \ 265 (int(bytes[2]) << 8) | (int(bytes[3]) << 0) 266 267def toIpNetmask(value): 268 if not isinstance(value, str): 269 raise TypeError, "wrong type '%s' should be str" % type(value) 270 271 (ip, netmask) = value.split('/') 272 ip = toIpAddress(ip) 273 netmaskParts = netmask.split('.') 274 if len(netmaskParts) == 1: 275 if not 0 <= int(netmask) <= 32: 276 raise ValueError, 'invalid netmask %s' % netmask 277 return (ip, int(netmask)) 278 elif len(netmaskParts) == 4: 279 netmaskNum = toIpAddress(netmask) 280 if netmaskNum == 0: 281 return (ip, 0) 282 testVal = 0 283 for i in range(32): 284 testVal |= (1 << (31 - i)) 285 if testVal == netmaskNum: 286 return (ip, i + 1) 287 raise ValueError, 'invalid netmask %s' % netmask 288 else: 289 raise ValueError, 'invalid netmask %s' % netmask 290 291def toIpWithPort(value): 292 if not isinstance(value, str): 293 raise TypeError, "wrong type '%s' should be str" % type(value) 294 295 (ip, port) = value.split(':') 296 ip = toIpAddress(ip) 297 if not 0 <= int(port) <= 0xffff: 298 raise ValueError, 'invalid port %s' % port 299 return (ip, int(port)) 300