File: //lib/python3/dist-packages/pyasn1/type/namedval.py
#
# This file is part of pyasn1 software.
#
# Copyright (c) 2005-2017, Ilya Etingof <etingof@gmail.com>
# License: http://snmplabs.com/pyasn1/license.html
#
# ASN.1 named integers
#
from pyasn1 import error
__all__ = ['NamedValues']
class NamedValues(object):
    """Create named values object.
    The |NamedValues| object represents a collection of string names
    associated with numeric IDs. These objects are used for giving
    names to otherwise numerical values.
    |NamedValues| objects are immutable and duck-type Python
    :class:`dict` object mapping ID to name and vice-versa.
    Parameters
    ----------
    \*args: variable number of two-element :py:class:`tuple`
        name: :py:class:`str`
            Value label
        value: :py:class:`int`
            Numeric value
    Keyword Args
    ------------
    name: :py:class:`str`
        Value label
    value: :py:class:`int`
        Numeric value
    Examples
    --------
    .. code-block:: pycon
        >>> nv = NamedValues('a', 'b', ('c', 0), d=1)
        >>> nv
        >>> {'c': 0, 'd': 1, 'a': 2, 'b': 3}
        >>> nv[0]
        'c'
        >>> nv['a']
        2
    """
    def __init__(self, *args, **kwargs):
        self.__names = {}
        self.__numbers = {}
        anonymousNames = []
        for namedValue in args:
            if isinstance(namedValue, (tuple, list)):
                try:
                    name, number = namedValue
                except ValueError:
                    raise error.PyAsn1Error('Not a proper attribute-value pair %r' % (namedValue,))
            else:
                anonymousNames.append(namedValue)
                continue
            if name in self.__names:
                raise error.PyAsn1Error('Duplicate name %s' % (name,))
            if number in self.__numbers:
                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))
            self.__names[name] = number
            self.__numbers[number] = name
        for name, number in kwargs.items():
            if name in self.__names:
                raise error.PyAsn1Error('Duplicate name %s' % (name,))
            if number in self.__numbers:
                raise error.PyAsn1Error('Duplicate number  %s=%s' % (name, number))
            self.__names[name] = number
            self.__numbers[number] = name
        if anonymousNames:
            number = self.__numbers and max(self.__numbers) + 1 or 0
            for name in anonymousNames:
                if name in self.__names:
                    raise error.PyAsn1Error('Duplicate name %s' % (name,))
                self.__names[name] = number
                self.__numbers[number] = name
                number += 1
    def __repr__(self):
        representation = ', '.join(['%s=%d' % x for x in self.items()])
        if len(representation) > 64:
            representation = representation[:32] + '...' + representation[-32:]
        return '<%s object 0x%x enums %s>' % (self.__class__.__name__, id(self), representation)
    def __eq__(self, other):
        return dict(self) == other
    def __ne__(self, other):
        return dict(self) != other
    def __lt__(self, other):
        return dict(self) < other
    def __le__(self, other):
        return dict(self) <= other
    def __gt__(self, other):
        return dict(self) > other
    def __ge__(self, other):
        return dict(self) >= other
    def __hash__(self):
        return hash(self.items())
    # Python dict protocol (read-only)
    def __getitem__(self, key):
        try:
            return self.__numbers[key]
        except KeyError:
            return self.__names[key]
    def __len__(self):
        return len(self.__names)
    def __contains__(self, key):
        return key in self.__names or key in self.__numbers
    def __iter__(self):
        return iter(self.__names)
    def values(self):
        return iter(self.__numbers)
    def keys(self):
        return iter(self.__names)
    def items(self):
        for name in self.__names:
            yield name, self.__names[name]
    # support merging
    def __add__(self, namedValues):
        return self.__class__(*tuple(self.items()) + tuple(namedValues.items()))
    # XXX clone/subtype?
    def clone(self, *args, **kwargs):
        new = self.__class__(*args, **kwargs)
        return self + new
    # legacy protocol
    def getName(self, value):
        if value in self.__numbers:
            return self.__numbers[value]
    def getValue(self, name):
        if name in self.__names:
            return self.__names[name]
    def getValues(self, *names):
        try:
            return [self.__names[name] for name in names]
        except KeyError:
            raise error.PyAsn1Error(
                'Unknown bit identifier(s): %s' % (set(names).difference(self.__names),)
            )