o
                         @   s   d Z ddlmZ ddlmZ ddlmZ ddlZddlZdZddd	d
ddddddddZddddddddddddZ	dd Z
d(ddZd)ddZd*ddZd+ddZd+dd Zd(d!d"Zd,d$d%Zd+d&d'ZdS )-z:Scaled integer ISO/IEC unit prefix parsing and formatting.    )absolute_import)division)unicode_literalsNz
    ^                           # Beginning of input marker.
    (?P<amount>\d+)             # Amount.
    ((?P<suffix>[-/a-zA-Z]+))?  # Optional scale and type abbr.
    $                           # End of input marker.
   i  i@B i ʚ;l    J)l     I5 i   i   i   @l        l           ) kMGTPkiMiGiTiPic                    s(   t t| dd d} fdd|D S )z:Returns a list of the units in scales sorted by magnitude.c                 S      | d | d fS Nr   r    valuer   r   D/tmp/google-cloud-sdk/lib/googlecloudsdk/core/util/scaled_integer.py<lambda>B       z#_UnitsByMagnitude.<locals>.<lambda>keyc                    s   g | ]
\}}|r|  qS r   r   ).0r   _	type_abbrr   r   
<listcomp>C   s    z%_UnitsByMagnitude.<locals>.<listcomp>)sortedsix	iteritems)unitsr   scale_itemsr   r   r   _UnitsByMagnitude?   s   
r%   Bc                 C   sV   | s| S |   }t|}t|  D ]}|s n||d  |kr$|d8 }q| d| S )z7Returns suffix with trailing type abbreviation deleted.r   N)upperlenreversed)suffixr   sicr   r   r   DeleteTypeAbbrF   s   r.   r   c              
   C   s   t | |}|s|}|sd}nB|drd|dd  }n4|d  }|dkr(d}t|dkr?|d dv r?|d7 }|d	d }n|dd }|rPtd
|| ||pSt|}|shtd|| dt	|d|S )a  Returns the size per unit for binary suffix string.

  Args:
    suffix: str, A case insensitive unit suffix string with optional type
      abbreviation.
    type_abbr: str, The optional case insensitive type abbreviation following
      the suffix.
    default_unit: The default unit prefix name.
    units: {str: int} map of unit prefix => size.

  Raises:
    ValueError: on unknown units of type suffix.

  Returns:
    The binary size per unit for a unit+type_abbr suffix.
  r   Kr   r   Nr   )r,   Ir,      z4Invalid type [{}] in [{}], expected [{}] or nothing.z2Invalid suffix [{}] in [{}], expected one of [{}].,)
r.   
startswithr'   r(   
ValueErrorformat_ISO_IEC_UNITSgetjoinr%   )r*   r   default_unitr#   prefixunitsizer   r   r   GetUnitSizeT   s6   


r=   c                 C   s   t | ||tdS )a  Returns the binary size per unit for binary suffix string.

  Args:
    suffix: str, A case insensitive unit suffix string with optional type
      abbreviation.
    type_abbr: str, The optional case insensitive type abbreviation following
      the suffix.
    default_unit: The default unit prefix name.

  Raises:
    ValueError for unknown units.

  Returns:
    The binary size per unit for a unit+type_abbr suffix.
  r   r9   r#   )r=   _BINARY_UNITS)r*   r   r9   r   r   r   GetBinaryUnitSize   s   r@   c           	   
   C   sz   t t|t j}|s#|rd| d nd}td||dt| ||dp)d}t	|||| d}t
|d}|| S )	a  Parses and returns a units scaled integer from string.

  ISO/IEC/SI rules relaxed to ignore case in unit and type names/abbreviations.

  Args:
    units: {str: int} map of unit prefix => size.
    string: The string to parse the integer + units.
    default_unit: The default unit prefix name.
    type_abbr: The optional type abbreviation suffix, validated but otherwise
      ignored.

  Raises:
    ValueError: on invalid input.

  Returns:
    The scaled integer value.
  []r   zB[{}] must the form INTEGER[UNIT]{} where units may be one of [{}].r2   r*   r>   amount)rematch_INTEGER_SUFFIX_TYPE_PATTERNVERBOSEr4   r5   r8   r%   groupr=   int)	r#   stringr9   r   rE   optional_type_abbrr*   r<   rC   r   r   r   _ParseScaledInteger   s   rL   c                 C      t t| ||dS )aj  Parses and returns an ISO Decimal/Binary scaled integer from string.

  ISO/IEC prefixes: 1k == 1000, 1ki == 1024.

  Args:
    string: The string to parse the integer + units.
    default_unit: The default unit prefix name.
    type_abbr: The optional type abbreviation suffix, validated but otherwise
      ignored.

  Returns:
    The scaled integer value.
  r9   r   )rL   r6   rJ   r9   r   r   r   r   ParseInteger   s   rP   c                 C   sV   t tttdd dD ]\}}|| kr$| | s$d| | ||  S qd| |S )zReturns a pretty string representation of an ISO Decimal value.

  Args:
    value: A scaled integer value.
    type_abbr: The optional type abbreviation suffix, validated but otherwise
      ignored.

  Returns:
    The formatted scaled integer value.
  c                 S   r   r   r   r   r   r   r   r      r   zFormatInteger.<locals>.<lambda>r   z{}{}{}{}{})r)   r    r!   r"   r6   r5   )r   r   r*   r<   r   r   r   FormatInteger   s   rR   c                 C   sr   t tttdd dD ]%\}}|| kr2|dkr| | rq| | }t|d}dj||||d  S qd| |S )	a  Returns a pretty string of a binary-base number with decimal precision.

  Args:
    value (float|int): A number.
    type_abbr (str): The optional type abbreviation suffix, validated but
      otherwise ignored.
    decimal_places (int): Number of decimal places to include of quotient for
      unit conversion. Does not allow rounding if -1. Will suffer float
      inaccuracy at high values.

  Returns:
    A formatted scaled value string.
  c                 S   r   r   r   r   r   r   r   r      r   z$FormatBinaryNumber.<locals>.<lambda>r   rS   r   z{:.{precision}f}{}{})	precisionrQ   )r)   r    r!   r"   r?   maxr5   )r   r   decimal_placesr*   r<   scaled_valuerT   r   r   r   FormatBinaryNumber   s   

	rX   c                 C   rM   )a  Parses and returns a Binary scaled integer from string.

  All ISO/IEC prefixes are powers of 2: 1k == 1ki == 1024. This is a
  concession to the inconsistent mix of binary/decimal unit measures for
  memory capacity, disk capacity, cpu speed. Ideally ParseInteger should be
  used.

  Args:
    string: The string to parse the integer + units.
    default_unit: The default unit prefix name.
    type_abbr: The optional type abbreviation suffix, validated but otherwise
      ignored.

  Returns:
    The scaled integer value.
  rN   )rL   r?   rO   r   r   r   ParseBinaryInteger   s   rY   )r&   )r&   r   N)r&   r   )r   r&   )r&   rS   )__doc__
__future__r   r   r   rD   r!   rF   r6   r?   r%   r.   r=   r@   rL   rP   rR   rX   rY   r   r   r   r   <module>   sP   


-

!

