|
Packit Service |
af52df |
import ctypes
|
|
Packit Service |
af52df |
from ctypes import POINTER, byref
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
import six
|
|
Packit Service |
af52df |
from decimal import Decimal
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
import locale
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
import gettext
|
|
Packit Service |
af52df |
_ = lambda x: gettext.translation("libbytesize", fallback=True).gettext(x) if x != "" else ""
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
"""
|
|
Packit Service |
af52df |
Python bindings for the libbytesize library and it's BSSize "class". These
|
|
Packit Service |
af52df |
bindings provide a real Python class :class:`Size` which wraps the libbytesize
|
|
Packit Service |
af52df |
functionality and provides all the features one would expect from a numeric type
|
|
Packit Service |
af52df |
in Python.
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
.. note::
|
|
Packit Service |
af52df |
``None`` is treated as ``Size(0)`` in mathematical operations.
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
"""
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
c_bytesize = ctypes.CDLL("libbytesize.so.1")
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
B = 0
|
|
Packit Service |
af52df |
KiB = 1
|
|
Packit Service |
af52df |
MiB = 2
|
|
Packit Service |
af52df |
GiB = 3
|
|
Packit Service |
af52df |
TiB = 4
|
|
Packit Service |
af52df |
PiB = 5
|
|
Packit Service |
af52df |
EiB = 6
|
|
Packit Service |
af52df |
ZiB = 7
|
|
Packit Service |
af52df |
YiB = 8
|
|
Packit Service |
af52df |
KB = 21
|
|
Packit Service |
af52df |
MB = 22
|
|
Packit Service |
af52df |
GB = 23
|
|
Packit Service |
af52df |
TB = 24
|
|
Packit Service |
af52df |
PB = 25
|
|
Packit Service |
af52df |
EB = 26
|
|
Packit Service |
af52df |
ZB = 27
|
|
Packit Service |
af52df |
YB = 28
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
ROUND_UP = 0
|
|
Packit Service |
af52df |
ROUND_DOWN = 1
|
|
Packit Service |
af52df |
ROUND_HALF_UP = 2
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
MAXUINT64 = 2**64 - 1
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
unit_strs = {
|
|
Packit Service |
af52df |
"B": B, "KiB": KiB, "MiB": MiB, "GiB": GiB, "TiB": TiB, "PiB": PiB, "EiB": EiB, "ZiB": ZiB, "YiB": YiB,
|
|
Packit Service |
af52df |
"KB": KB, "MB": MB, "GB": GB, "TB": TB, "PB": PB, "EB": EB, "ZB": ZB, "YB": YB,
|
|
Packit Service |
af52df |
}
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def unit_str(unit, xlate=False):
|
|
Packit Service |
af52df |
for (u_str, u) in unit_strs.items():
|
|
Packit Service |
af52df |
if u == unit:
|
|
Packit Service |
af52df |
return _(u_str) if xlate else u_str
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class SizeErrorStruct(ctypes.Structure):
|
|
Packit Service |
af52df |
_fields_ = [("code", ctypes.c_int),
|
|
Packit Service |
af52df |
("msg", ctypes.c_char_p)]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class SizeError(Exception):
|
|
Packit Service |
af52df |
pass
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class InvalidSpecError(SizeError):
|
|
Packit Service |
af52df |
pass
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class OverflowError(SizeError):
|
|
Packit Service |
af52df |
pass
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class ZeroDivisionError(SizeError):
|
|
Packit Service |
af52df |
pass
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
_error_code_clss = (InvalidSpecError, OverflowError, ZeroDivisionError)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def get_error(err):
|
|
Packit Service |
af52df |
if not err:
|
|
Packit Service |
af52df |
return None
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
msg = str(err.contents.msg, "utf-8")
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
msg = err.contents.msg
|
|
Packit Service |
af52df |
ex = _error_code_clss[err.contents.code](msg)
|
|
Packit Service |
af52df |
c_bytesize.bs_clear_error(byref(err))
|
|
Packit Service |
af52df |
raise ex
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class SizeStruct(ctypes.Structure):
|
|
Packit Service |
af52df |
@classmethod
|
|
Packit Service |
af52df |
def new(cls):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_new().contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@classmethod
|
|
Packit Service |
af52df |
def new_from_bytes(cls, byts, sgn):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_new_from_bytes(byts, sgn).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@classmethod
|
|
Packit Service |
af52df |
def new_from_str(cls, s):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
s = bytes(s, "utf-8")
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_new_from_str(s, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@classmethod
|
|
Packit Service |
af52df |
def new_from_size(cls, sz):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_new_from_size(sz).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __del__(self):
|
|
Packit Service |
af52df |
# XXX: For some reason c_bytesize may be None here (probably when python
|
|
Packit Service |
af52df |
# cleans up after itself) and loading it again doesn't work at that
|
|
Packit Service |
af52df |
# stage. Let's just prevent ignored exceptions from happening.
|
|
Packit Service |
af52df |
if c_bytesize:
|
|
Packit Service |
af52df |
c_bytesize.bs_size_free(self)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def get_bytes(self):
|
|
Packit Service |
af52df |
sgn = ctypes.c_int(0)
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_get_bytes(self, byref(sgn), byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return (ret, sgn.value)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def get_bytes_str(self):
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
return str(c_bytesize.bs_size_get_bytes_str(self), "utf-8")
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_get_bytes_str(self)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def add(self, sz):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_add(self, sz).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def add_bytes(self, b):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_add_bytes(self, b).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def grow(self, sz):
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow(self, sz)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def grow_bytes(self, b):
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_bytes(self, b)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def sub(self, sz):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_sub(self, sz).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def sub_bytes(self, b):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_sub_bytes(self, b).contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def shrink(self, sz):
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink(self, sz)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def shrink_bytes(self, b):
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_bytes(self, b)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def cmp(self, sz, ign_sgn):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_cmp(self, sz, ign_sgn)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def cmp_bytes(self, b, ign_sgn):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_cmp_bytes(self, b, ign_sgn)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def convert_to(self, unit):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_convert_to(self, unit, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
ret = str(ret, "utf-8")
|
|
Packit Service |
af52df |
return ret
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def div(self, sz):
|
|
Packit Service |
af52df |
sgn = ctypes.c_int(0)
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_div(self, sz, byref(sgn), byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return (ret, sgn.value)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def div_int(self, div):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_div_int(self, div, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def shrink_div_int(self, div):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_div_int(self, div, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def human_readable(self, min_unit, max_places, xlate):
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
return str(c_bytesize.bs_size_human_readable(self, min_unit, max_places, xlate), "utf-8")
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_human_readable(self, min_unit, max_places, xlate)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def sgn(self):
|
|
Packit Service |
af52df |
return c_bytesize.bs_size_sgn(self)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def true_div(self, sz):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_true_div(self, sz, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
ret = str(ret, "utf-8")
|
|
Packit Service |
af52df |
return ret
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def true_div_int(self, div):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_true_div_int(self, div, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
ret = str(ret, "utf-8")
|
|
Packit Service |
af52df |
return ret
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def mod(self, sz):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_mod(self, sz, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def mul_float_str(self, fl_str):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
fl_str = bytes(fl_str, "utf-8")
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_mul_float_str(self, fl_str, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def grow_mul_float_str(self, fl_str):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
if six.PY3:
|
|
Packit Service |
af52df |
fl_str = bytes(fl_str, "utf-8")
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_float_str(self, fl_str, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def mul_int(self, i):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_mul_int(self, i)
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def grow_mul_int(self, i):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_int(self, i)
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return self
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def round_to_nearest(self, sz, dir):
|
|
Packit Service |
af52df |
err = POINTER(SizeErrorStruct)()
|
|
Packit Service |
af52df |
ret = c_bytesize.bs_size_round_to_nearest(self, sz, dir, byref(err))
|
|
Packit Service |
af52df |
get_error(err)
|
|
Packit Service |
af52df |
return ret.contents
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __repr__(self):
|
|
Packit Service |
af52df |
return "Size (%s)" % self.human_readable(B, -1, False)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## Constructors
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new.argtypes = []
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_bytes.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_bytes.argtypes = [ctypes.c_ulonglong, ctypes.c_int]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_str.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_str.argtypes = [ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_size.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_new_from_size.argtypes = [POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## Destructors
|
|
Packit Service |
af52df |
c_bytesize.bs_size_free.restype = None
|
|
Packit Service |
af52df |
c_bytesize.bs_size_free.argtypes = [POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_clear_error.restype = None
|
|
Packit Service |
af52df |
c_bytesize.bs_clear_error.argtypes = [POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## Query methods
|
|
Packit Service |
af52df |
c_bytesize.bs_size_get_bytes.restype = ctypes.c_ulonglong
|
|
Packit Service |
af52df |
c_bytesize.bs_size_get_bytes.argtypes = [POINTER(SizeStruct), POINTER(ctypes.c_int), POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sgn.restype = ctypes.c_int
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sgn.argtypes = [POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_get_bytes_str.restype = ctypes.c_char_p
|
|
Packit Service |
af52df |
c_bytesize.bs_size_get_bytes_str.argtypes = [POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_convert_to.restype = ctypes.c_char_p
|
|
Packit Service |
af52df |
c_bytesize.bs_size_convert_to.argtypes = [POINTER(SizeStruct), ctypes.c_int, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_human_readable.restype = ctypes.c_char_p
|
|
Packit Service |
af52df |
c_bytesize.bs_size_human_readable.argtypes = [POINTER(SizeStruct), ctypes.c_int, ctypes.c_int, ctypes.c_bool]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## Arithmetic
|
|
Packit Service |
af52df |
c_bytesize.bs_size_add.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_add.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_add_bytes.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_add_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_bytes.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sub.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sub.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct)]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sub_bytes.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_sub_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_bytes.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mul_int.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mul_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_int.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mul_float_str.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mul_float_str.argtypes = [POINTER(SizeStruct), ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_float_str.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_grow_mul_float_str.argtypes = [POINTER(SizeStruct), ctypes.c_char_p, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_div.restype = ctypes.c_ulonglong
|
|
Packit Service |
af52df |
c_bytesize.bs_size_div.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(ctypes.c_int), POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_div_int.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_div_int.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_shrink_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_true_div.restype = ctypes.c_char_p
|
|
Packit Service |
af52df |
c_bytesize.bs_size_true_div.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_true_div_int.restype = ctypes.c_char_p
|
|
Packit Service |
af52df |
c_bytesize.bs_size_true_div_int.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mod.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_mod.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_round_to_nearest.restype = POINTER(SizeStruct)
|
|
Packit Service |
af52df |
c_bytesize.bs_size_round_to_nearest.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), ctypes.c_int, POINTER(POINTER(SizeErrorStruct))]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## Comparisons
|
|
Packit Service |
af52df |
c_bytesize.bs_size_cmp.restype = ctypes.c_int
|
|
Packit Service |
af52df |
c_bytesize.bs_size_cmp.argtypes = [POINTER(SizeStruct), POINTER(SizeStruct), ctypes.c_bool]
|
|
Packit Service |
af52df |
c_bytesize.bs_size_cmp_bytes.restype = ctypes.c_int
|
|
Packit Service |
af52df |
c_bytesize.bs_size_cmp_bytes.argtypes = [POINTER(SizeStruct), ctypes.c_ulonglong, ctypes.c_bool]
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def _str_to_decimal(num_str):
|
|
Packit Service |
af52df |
radix = locale.nl_langinfo(locale.RADIXCHAR)
|
|
Packit Service |
af52df |
if radix != '.':
|
|
Packit Service |
af52df |
num_str = num_str.replace(radix, '.')
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
return Decimal(num_str)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def neutralize_none_operand(fn):
|
|
Packit Service |
af52df |
def fn_with_neutralization(sz, other):
|
|
Packit Service |
af52df |
return fn(sz, Size(0) if other is None else other)
|
|
Packit Service |
af52df |
return fn_with_neutralization
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
class Size(object):
|
|
Packit Service |
af52df |
def __init__(self, spec=None):
|
|
Packit Service |
af52df |
self._c_size = None
|
|
Packit Service |
af52df |
try:
|
|
Packit Service |
af52df |
if isinstance(spec, six.string_types):
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_str(spec)
|
|
Packit Service |
af52df |
elif isinstance(spec, six.integer_types):
|
|
Packit Service |
af52df |
abs_val = abs(spec)
|
|
Packit Service |
af52df |
if abs_val == spec:
|
|
Packit Service |
af52df |
sgn = 1
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
sgn = -1
|
|
Packit Service |
af52df |
if abs_val <= MAXUINT64:
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_bytes(abs_val, sgn)
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_str(str(spec))
|
|
Packit Service |
af52df |
elif isinstance(spec, (Decimal, float)):
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_str(str(spec))
|
|
Packit Service |
af52df |
elif isinstance(spec, SizeStruct):
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_size(spec)
|
|
Packit Service |
af52df |
elif isinstance(spec, Size):
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new_from_size(spec._c_size)
|
|
Packit Service |
af52df |
elif spec is None:
|
|
Packit Service |
af52df |
self._c_size = SizeStruct.new()
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
raise ValueError("Cannot construct new size from '%s'" % spec)
|
|
Packit Service |
af52df |
except SizeError as e:
|
|
Packit Service |
af52df |
raise ValueError(e)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## METHODS ##
|
|
Packit Service |
af52df |
def get_bytes(self):
|
|
Packit Service |
af52df |
try:
|
|
Packit Service |
af52df |
val, sgn = self._c_size.get_bytes()
|
|
Packit Service |
af52df |
return val * sgn
|
|
Packit Service |
af52df |
except SizeError:
|
|
Packit Service |
af52df |
return int(self._c_size.get_bytes_str())
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def convert_to(self, unit):
|
|
Packit Service |
af52df |
if isinstance(unit, six.string_types):
|
|
Packit Service |
af52df |
real_unit = unit_strs.get(unit)
|
|
Packit Service |
af52df |
if real_unit is None:
|
|
Packit Service |
af52df |
raise ValueError("Invalid unit specification: '%s'" % unit)
|
|
Packit Service |
af52df |
ret = self._c_size.convert_to(real_unit)
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
ret = self._c_size.convert_to(unit)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
return _str_to_decimal(ret)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def human_readable(self, min_unit=B, max_places=2, xlate=True):
|
|
Packit Service |
af52df |
if isinstance(min_unit, six.string_types):
|
|
Packit Service |
af52df |
if min_unit in unit_strs.keys():
|
|
Packit Service |
af52df |
min_unit = unit_strs[min_unit]
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
raise ValueError("Invalid unit specification: '%s'" % min_unit)
|
|
Packit Service |
af52df |
if not isinstance(max_places, six.integer_types):
|
|
Packit Service |
af52df |
raise ValueError("max_places has to be an integer number")
|
|
Packit Service |
af52df |
return self._c_size.human_readable(min_unit, max_places, xlate)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def round_to_nearest(self, round_to, rounding):
|
|
Packit Service |
af52df |
if isinstance(round_to, Size):
|
|
Packit Service |
af52df |
return self._c_size.round_to_nearest(round_to._c_size, rounding)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
size = None
|
|
Packit Service |
af52df |
# else try to create a SizeStruct instance from it
|
|
Packit Service |
af52df |
for (unit_str, unit) in unit_strs.items():
|
|
Packit Service |
af52df |
if round_to in (unit.real, unit_str):
|
|
Packit Service |
af52df |
size = SizeStruct.new_from_str("1 %s" % unit_str)
|
|
Packit Service |
af52df |
break
|
|
Packit Service |
af52df |
if size is not None:
|
|
Packit Service |
af52df |
return Size(self._c_size.round_to_nearest(size, rounding))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
raise ValueError("Invalid size specification: '%s'" % round_to)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def cmp(self, other, abs_vals=False):
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if (other < 0 and abs_vals):
|
|
Packit Service |
af52df |
other = abs(other)
|
|
Packit Service |
af52df |
if 0 <= other <= MAXUINT64:
|
|
Packit Service |
af52df |
return self._c_size.cmp_bytes(other, abs_vals)
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)):
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, Size):
|
|
Packit Service |
af52df |
other = other._c_size
|
|
Packit Service |
af52df |
elif other is None:
|
|
Packit Service |
af52df |
return 1
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
return self._c_size.cmp(other, abs_vals)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
## INTERNAL METHODS ##
|
|
Packit Service |
af52df |
def __eq__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) == 0
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __ne__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) != 0
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __lt__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) == -1
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __le__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) in (-1, 0)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __gt__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) == 1
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __ge__(self, other):
|
|
Packit Service |
af52df |
return self.cmp(other, False) in (1, 0)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __bool__(self):
|
|
Packit Service |
af52df |
return self.get_bytes() != 0
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
__nonzero__ = __bool__
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __abs__(self):
|
|
Packit Service |
af52df |
return Size(abs(self.get_bytes()))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __neg__(self):
|
|
Packit Service |
af52df |
return self.__mul__(-1)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __add__(self, other):
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if other <= MAXUINT64:
|
|
Packit Service |
af52df |
return Size(self._c_size.add_bytes(other))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)):
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, Size):
|
|
Packit Service |
af52df |
other = other._c_size
|
|
Packit Service |
af52df |
return Size(self._c_size.add(other))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
# needed to make sum() work with Size arguments
|
|
Packit Service |
af52df |
__radd__ = __add__
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __sub__(self, other):
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if other <= MAXUINT64:
|
|
Packit Service |
af52df |
return Size(self._c_size.sub_bytes(other))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)):
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
elif isinstance(other, Size):
|
|
Packit Service |
af52df |
other = other._c_size
|
|
Packit Service |
af52df |
return Size(self._c_size.sub(other))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __rsub__(self, other):
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
return Size(SizeStruct.sub(other, self._c_size))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __mul__(self, other):
|
|
Packit Service |
af52df |
if isinstance(other, (Size, SizeStruct)):
|
|
Packit Service |
af52df |
raise ValueError("Cannot multiply Size by Size. It just doesn't make sense.")
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)) or (isinstance(other, six.integer_types)
|
|
Packit Service |
af52df |
and other > MAXUINT64 or other < 0):
|
|
Packit Service |
af52df |
return Size(self._c_size.mul_float_str(str(other)))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
return Size(self._c_size.mul_int(other))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
__rmul__ = __mul__
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __div__(self, other):
|
|
Packit Service |
af52df |
if not six.PY2:
|
|
Packit Service |
af52df |
raise AttributeError
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if other <= MAXUINT64:
|
|
Packit Service |
af52df |
return Size(self._c_size.div_int(other))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
return Size(_str_to_decimal(self._c_size.true_div(other)))
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)):
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
return Size(self._c_size.true_div(other))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
return _str_to_decimal(self._c_size.true_div(other._c_size))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __truediv__(self, other):
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if other <= MAXUINT64:
|
|
Packit Service |
af52df |
return Size(self._c_size.true_div_int(other))
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
return Size(self._c_size.true_div(other))
|
|
Packit Service |
af52df |
elif isinstance(other, (Decimal, float)):
|
|
Packit Service |
af52df |
return Size(self._c_size.mul_float_str(str(Decimal(1)/Decimal(other))))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
return _str_to_decimal(self._c_size.true_div(other._c_size))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def _safe_floordiv(self, other):
|
|
Packit Service |
af52df |
try:
|
|
Packit Service |
af52df |
val, sgn = self._c_size.div(other._c_size)
|
|
Packit Service |
af52df |
return val * sgn
|
|
Packit Service |
af52df |
except OverflowError:
|
|
Packit Service |
af52df |
return int(float(self._c_size.true_div(other._c_size)))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def _safe_floordiv_int(self, other):
|
|
Packit Service |
af52df |
try:
|
|
Packit Service |
af52df |
return Size(self._c_size.div_int(other))
|
|
Packit Service |
af52df |
except OverflowError:
|
|
Packit Service |
af52df |
return Size(float(self._c_size.true_div_int(other)))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __floordiv__(self, other):
|
|
Packit Service |
af52df |
if isinstance(other, six.integer_types):
|
|
Packit Service |
af52df |
if other <= MAXUINT64:
|
|
Packit Service |
af52df |
return self._safe_floordiv_int(other)
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
other = SizeStruct.new_from_str(str(other))
|
|
Packit Service |
af52df |
return Size(self._safe_floordiv(other))
|
|
Packit Service |
af52df |
return self._safe_floordiv(other)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __mod__(self, other):
|
|
Packit Service |
af52df |
return Size(self._c_size.mod(other._c_size))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
@neutralize_none_operand
|
|
Packit Service |
af52df |
def __divmod__(self, other):
|
|
Packit Service |
af52df |
rdiv = self.__floordiv__(other)
|
|
Packit Service |
af52df |
if not isinstance(other, Size):
|
|
Packit Service |
af52df |
rmod = self.__mod__(rdiv)
|
|
Packit Service |
af52df |
else:
|
|
Packit Service |
af52df |
rmod = self.__mod__(other)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
return (rdiv, rmod)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __repr__(self):
|
|
Packit Service |
af52df |
return "Size (%s)" % self.human_readable(B, -1, False)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __str__(self):
|
|
Packit Service |
af52df |
return self.human_readable()
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __int__(self):
|
|
Packit Service |
af52df |
return self.get_bytes()
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __float__(self):
|
|
Packit Service |
af52df |
return float(self.get_bytes())
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __deepcopy__(self, memo_dict):
|
|
Packit Service |
af52df |
return Size(self)
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
# pickling support for Size
|
|
Packit Service |
af52df |
# see https://docs.python.org/3/library/pickle.html#object.__reduce__
|
|
Packit Service |
af52df |
def __reduce__(self):
|
|
Packit Service |
af52df |
return (self.__class__, (self.get_bytes(),))
|
|
Packit Service |
af52df |
|
|
Packit Service |
af52df |
def __hash__(self):
|
|
Packit Service |
af52df |
return self.get_bytes()
|