00000024
  "   lY>d
n-jvOe1hm     #
# Copyright (c) 2018 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. 
#

"""
  SizeString - LVM-style size strings

  $Id: //eng/vdo-releases/magnesium/src/python/vdo/vdomgmnt/SizeString.py#1 $

"""
import locale
from . import Constants

class SizeString(object):
  """Represents the size of an object such as a disk partition.

  Conversions are provided to and from suffixed size strings as used
  by LVM commands like lvcreate(8). These strings consist of a
  (possibly floating-point) number followed by an optional unit
  suffix: B (bytes), S (512-byte sectors), and KMGTPE for kilobytes
  through exabytes, respectively. Suffixes are not case-sensitive; the
  default unit is Megabytes. Currently, we reject negative sizes.

  Unlike some (but not all) LVM commands we do not interpret the upper-case
  version of a suffix as a power of ten.

  Attributes:
    _originalString (str): the original string we were constructed
      with, mainly used for debugging
    _bytes (int): the value of this object in bytes

  """

  ######################################################################
  # Public methods
  ######################################################################
  def __add__(self, rhs):
    retval = SizeString("")
    retval._bytes = self._bytes + int(rhs)
    return retval

  ######################################################################
  def __bool__(self):
    return self._bytes != 0

  ######################################################################
  def __cmp__(self, rhs):
    result = 0
    if not isinstance(rhs, SizeString):
      result = NotImplemented
    else:
      result = cmp(self._bytes, rhs.toBytes())
    return result

  ######################################################################
  def __iadd__(self, rhs):
    self._bytes += int(rhs)
    return self

  ######################################################################
  def __int__(self):
    return self._bytes

  ######################################################################
  def __nonzero__(self):
    return self.__bool__()

  ######################################################################
  def asLvmText(self):
    """Returns this object as a size string without a decimal point."""
    suffix = Constants.lvmDefaultSuffix
    size = self._bytes
    if size > 0:
      for click in Constants.lvmSiSuffixes[::-1]:
        divisor = Constants.lvmSiSuffixSizeMap[click]
        if size % divisor == 0:
          size = size // divisor
          suffix = click
          break
      else:
          suffix = Constants.lvmByteSuffix

    return str(size) + suffix.upper()

  ######################################################################
  def roundToBlock(self):
    """Rounds this object down to a multiple of the block size."""
    self._bytes = self.toBlocks() * Constants.VDO_BLOCK_SIZE
    return self

  ######################################################################
  def toBlocks(self):
    """Returns this object as a count of 4K blocks, rounding down."""
    return (self._bytes // Constants.VDO_BLOCK_SIZE)

  ######################################################################
  def toBytes(self):
    """Returns the count of bytes represented by this object."""
    return self._bytes

  ######################################################################
  