else/Bytestring/bytestring.py
Ethan Dalool 53645b0123 else
2016-08-09 01:33:36 -07:00

84 lines
No EOL
2.3 KiB
Python

import re
BYTE = 1
KIBIBYTE = 1024 * BYTE
MIBIBYTE = 1024 * KIBIBYTE
GIBIBYTE = 1024 * MIBIBYTE
TEBIBYTE = 1024 * GIBIBYTE
PEBIBYTE = 1024 * TEBIBYTE
EXIBYTE = 1024 * PEBIBYTE
ZEBIBYTE = 1024 * EXIBYTE
YOBIBYTE = 1024 * ZEBIBYTE
UNIT_STRINGS = {
BYTE: 'b',
KIBIBYTE: 'KiB',
MIBIBYTE: 'MiB',
GIBIBYTE: 'GiB',
TEBIBYTE: 'TiB',
PEBIBYTE: 'PiB',
EXIBYTE: 'EiB',
ZEBIBYTE: 'ZiB',
YOBIBYTE: 'YiB',
}
UNITS_SORTED = sorted(UNIT_STRINGS.keys(), reverse=True)
def bytestring(size, force_unit=None):
'''
Convert a number into a binary-standard string.
force_unit:
If None, an appropriate size unit is chosen automatically.
Otherwise, you can provide one of the size constants to force that divisor.
'''
if force_unit is None:
divisor = get_appropriate_divisor(size)
else:
divisor = force_unit
size_unit_string = UNIT_STRINGS[divisor]
size_string = '%.3f %s' % ((size / divisor), size_unit_string)
return size_string
def get_appropriate_divisor(size):
size = abs(size)
for unit in UNITS_SORTED:
if size >= unit:
appropriate_unit = unit
break
else:
appropriate_unit = 1
return appropriate_unit
def parsebytes(string):
'''
Given a string like "100 kib", return the appropriate integer value.
'''
string = string.lower().strip().replace(' ', '')
matches = re.findall('((\\.|-|\\d)+)', string)
if len(matches) == 0:
raise ValueError('No numbers found')
if len(matches) > 1:
raise ValueError('Too many numbers found')
byte_value = matches[0][0]
if not string.startswith(byte_value):
raise ValueError('Number is not at start of string')
# if the string has no text besides the number, just return that int.
string = string.replace(byte_value, '')
byte_value = float(byte_value)
if string == '':
return int(byte_value)
reversed_units = {value.lower():key for (key, value) in UNIT_STRINGS.items()}
for (unit_string, multiplier) in reversed_units.items():
# accept kib, k, kb
if string in (unit_string, unit_string[0], unit_string.replace('i', '')):
break
else:
raise ValueError('Could not determine byte value of %s' % string)
return int(byte_value * multiplier)