from exceptions import UnitError from bytes import Bytes def onlysectors(msg): def decorator(func): def check_other(self, other): if not isinstance(other, Sectors): raise UnitError(msg) return func(self, other) return check_other return decorator class Sectors(object): def __init__(self, quantity, sector_size): if isinstance(sector_size, Bytes): self.sector_size = sector_size else: self.sector_size = Bytes(sector_size) if isinstance(quantity, Bytes): self.bytes = quantity else: if isinstance(quantity, (int, long)): self.bytes = self.sector_size * quantity else: self.bytes = Bytes(quantity) def get_sectors(self): return self.bytes / self.sector_size def __repr__(self): return str(self.get_sectors()) + 's' def __str__(self): return self.__repr__() def __int__(self): return self.get_sectors() def __long__(self): return self.get_sectors() @onlysectors('Can only compare sectors with sectors') def __lt__(self, other): return self.bytes < other.bytes @onlysectors('Can only compare sectors with sectors') def __le__(self, other): return self.bytes <= other.bytes @onlysectors('Can only compare sectors with sectors') def __eq__(self, other): return self.bytes == other.bytes @onlysectors('Can only compare sectors with sectors') def __ne__(self, other): return self.bytes != other.bytes @onlysectors('Can only compare sectors with sectors') def __ge__(self, other): return self.bytes >= other.bytes @onlysectors('Can only compare sectors with sectors') def __gt__(self, other): return self.bytes > other.bytes def __add__(self, other): if isinstance(other, (int, long)): return Sectors(self.bytes + self.sector_size * other, self.sector_size) if isinstance(other, Bytes): return Sectors(self.bytes + other, self.sector_size) if isinstance(other, Sectors): if self.sector_size != other.sector_size: raise UnitError('Cannot sum sectors with different sector sizes') return Sectors(self.bytes + other.bytes, self.sector_size) raise UnitError('Can only add sectors, bytes or integers to sectors') def __iadd__(self, other): if isinstance(other, (int, long)): self.bytes += self.sector_size * other return self if isinstance(other, Bytes): self.bytes += other return self if isinstance(other, Sectors): if self.sector_size != other.sector_size: raise UnitError('Cannot sum sectors with different sector sizes') self.bytes += other.bytes return self raise UnitError('Can only add sectors, bytes or integers to sectors') def __sub__(self, other): if isinstance(other, (int, long)): return Sectors(self.bytes - self.sector_size * other, self.sector_size) if isinstance(other, Bytes): return Sectors(self.bytes - other, self.sector_size) if isinstance(other, Sectors): if self.sector_size != other.sector_size: raise UnitError('Cannot subtract sectors with different sector sizes') return Sectors(self.bytes - other.bytes, self.sector_size) raise UnitError('Can only subtract sectors, bytes or integers from sectors') def __isub__(self, other): if isinstance(other, (int, long)): self.bytes -= self.sector_size * other return self if isinstance(other, Bytes): self.bytes -= other return self if isinstance(other, Sectors): if self.sector_size != other.sector_size: raise UnitError('Cannot subtract sectors with different sector sizes') self.bytes -= other.bytes return self raise UnitError('Can only subtract sectors, bytes or integers from sectors') def __mul__(self, other): if isinstance(other, (int, long)): return Sectors(self.bytes * other, self.sector_size) else: raise UnitError('Can only multiply sectors with integers') def __imul__(self, other): if isinstance(other, (int, long)): self.bytes *= other return self else: raise UnitError('Can only multiply sectors with integers') def __div__(self, other): if isinstance(other, (int, long)): return Sectors(self.bytes / other, self.sector_size) if isinstance(other, Sectors): if self.sector_size == other.sector_size: return self.bytes / other.bytes else: raise UnitError('Cannot divide sectors with different sector sizes') raise UnitError('Can only divide sectors with integers or sectors') def __idiv__(self, other): if isinstance(other, (int, long)): self.bytes /= other return self if isinstance(other, Sectors): if self.sector_size == other.sector_size: self.bytes /= other.bytes return self else: raise UnitError('Cannot divide sectors with different sector sizes') raise UnitError('Can only divide sectors with integers or sectors') @onlysectors('Can only take modulus of sectors with sectors') def __mod__(self, other): if self.sector_size == other.sector_size: return Sectors(self.bytes % other.bytes, self.sector_size) else: raise UnitError('Cannot take modulus of sectors with different sector sizes') @onlysectors('Can only take modulus of sectors with sectors') def __imod__(self, other): if self.sector_size == other.sector_size: self.bytes %= other.bytes return self else: raise UnitError('Cannot take modulus of sectors with different sector sizes') def __getstate__(self): return {'__class__': self.__module__ + '.' + self.__class__.__name__, 'sector_size': self.sector_size, 'bytes': self.bytes, } def __setstate__(self, state): self.sector_size = state['sector_size'] self.bytes = state['bytes']