Home | History | Annotate | Download | only in type
      1 # Base classes for ASN.1 types
      2 import sys
      3 from pyasn1.type import constraint, tagmap
      4 from pyasn1 import error
      5 
      6 class Asn1Item: pass
      7 
      8 class Asn1ItemBase(Asn1Item):
      9     # Set of tags for this ASN.1 type
     10     tagSet = ()
     11     
     12     # A list of constraint.Constraint instances for checking values
     13     subtypeSpec = constraint.ConstraintsIntersection()
     14 
     15     # Used for ambiguous ASN.1 types identification
     16     typeId = None
     17     
     18     def __init__(self, tagSet=None, subtypeSpec=None):
     19         if tagSet is None:
     20             self._tagSet = self.tagSet
     21         else:
     22             self._tagSet = tagSet
     23         if subtypeSpec is None:
     24             self._subtypeSpec = self.subtypeSpec
     25         else:
     26             self._subtypeSpec = subtypeSpec
     27 
     28     def _verifySubtypeSpec(self, value, idx=None):
     29         try:
     30             self._subtypeSpec(value, idx)
     31         except error.PyAsn1Error:
     32             c, i, t = sys.exc_info()
     33             raise c('%s at %s' % (i, self.__class__.__name__))
     34         
     35     def getSubtypeSpec(self): return self._subtypeSpec
     36     
     37     def getTagSet(self): return self._tagSet
     38     def getEffectiveTagSet(self): return self._tagSet  # used by untagged types
     39     def getTagMap(self): return tagmap.TagMap({self._tagSet: self})
     40     
     41     def isSameTypeWith(self, other):
     42         return self is other or \
     43                self._tagSet == other.getTagSet() and \
     44                self._subtypeSpec == other.getSubtypeSpec()
     45     def isSuperTypeOf(self, other):
     46         """Returns true if argument is a ASN1 subtype of ourselves"""
     47         return self._tagSet.isSuperTagSetOf(other.getTagSet()) and \
     48                self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec())
     49 
     50 class __NoValue:
     51     def __getattr__(self, attr):
     52         raise error.PyAsn1Error('No value for %s()' % attr)
     53     def __getitem__(self, i):
     54         raise error.PyAsn1Error('No value')
     55     
     56 noValue = __NoValue()
     57 
     58 # Base class for "simple" ASN.1 objects. These are immutable.
     59 class AbstractSimpleAsn1Item(Asn1ItemBase):    
     60     defaultValue = noValue
     61     def __init__(self, value=None, tagSet=None, subtypeSpec=None):
     62         Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
     63         if value is None or value is noValue:
     64             value = self.defaultValue
     65         if value is None or value is noValue:
     66             self.__hashedValue = value = noValue
     67         else:
     68             value = self.prettyIn(value)
     69             self._verifySubtypeSpec(value)
     70             self.__hashedValue = hash(value)
     71         self._value = value
     72         self._len = None
     73         
     74     def __repr__(self):
     75         if self._value is noValue:
     76             return self.__class__.__name__ + '()'
     77         else:
     78             return self.__class__.__name__ + '(%s)' % (self.prettyOut(self._value),)
     79     def __str__(self): return str(self._value)
     80     def __eq__(self, other):
     81         return self is other and True or self._value == other
     82     def __ne__(self, other): return self._value != other
     83     def __lt__(self, other): return self._value < other
     84     def __le__(self, other): return self._value <= other
     85     def __gt__(self, other): return self._value > other
     86     def __ge__(self, other): return self._value >= other
     87     if sys.version_info[0] <= 2:
     88         def __nonzero__(self): return bool(self._value)
     89     else:
     90         def __bool__(self): return bool(self._value)
     91     def __hash__(self): return self.__hashedValue
     92 
     93     def clone(self, value=None, tagSet=None, subtypeSpec=None):
     94         if value is None and tagSet is None and subtypeSpec is None:
     95             return self
     96         if value is None:
     97             value = self._value
     98         if tagSet is None:
     99             tagSet = self._tagSet
    100         if subtypeSpec is None:
    101             subtypeSpec = self._subtypeSpec
    102         return self.__class__(value, tagSet, subtypeSpec)
    103 
    104     def subtype(self, value=None, implicitTag=None, explicitTag=None,
    105                 subtypeSpec=None):
    106         if value is None:
    107             value = self._value
    108         if implicitTag is not None:
    109             tagSet = self._tagSet.tagImplicitly(implicitTag)
    110         elif explicitTag is not None:
    111             tagSet = self._tagSet.tagExplicitly(explicitTag)
    112         else:
    113             tagSet = self._tagSet
    114         if subtypeSpec is None:
    115             subtypeSpec = self._subtypeSpec
    116         else:
    117             subtypeSpec = subtypeSpec + self._subtypeSpec
    118         return self.__class__(value, tagSet, subtypeSpec)
    119 
    120     def prettyIn(self, value): return value
    121     def prettyOut(self, value): return str(value)
    122 
    123     def prettyPrint(self, scope=0):
    124         if self._value is noValue:
    125             return '<no value>'
    126         else:
    127             return self.prettyOut(self._value)
    128 
    129     # XXX Compatibility stub
    130     def prettyPrinter(self, scope=0): return self.prettyPrint(scope)
    131     
    132 #
    133 # Constructed types:
    134 # * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
    135 # * ASN1 types and values are represened by Python class instances
    136 # * Value initialization is made for defaulted components only
    137 # * Primary method of component addressing is by-position. Data model for base
    138 #   type is Python sequence. Additional type-specific addressing methods
    139 #   may be implemented for particular types.
    140 # * SequenceOf and SetOf types do not implement any additional methods
    141 # * Sequence, Set and Choice types also implement by-identifier addressing
    142 # * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing
    143 # * Sequence and Set types may include optional and defaulted
    144 #   components
    145 # * Constructed types hold a reference to component types used for value
    146 #   verification and ordering.
    147 # * Component type is a scalar type for SequenceOf/SetOf types and a list
    148 #   of types for Sequence/Set/Choice.
    149 #
    150 
    151 class AbstractConstructedAsn1Item(Asn1ItemBase):
    152     componentType = None
    153     sizeSpec = constraint.ConstraintsIntersection()
    154     def __init__(self, componentType=None, tagSet=None,
    155                  subtypeSpec=None, sizeSpec=None):
    156         Asn1ItemBase.__init__(self, tagSet, subtypeSpec)
    157         if componentType is None:
    158             self._componentType = self.componentType
    159         else:
    160             self._componentType = componentType
    161         if sizeSpec is None:
    162             self._sizeSpec = self.sizeSpec
    163         else:
    164             self._sizeSpec = sizeSpec
    165         self._componentValues = []
    166         self._componentValuesSet = 0
    167 
    168     def __repr__(self):
    169         r = self.__class__.__name__ + '()'
    170         for idx in range(len(self._componentValues)):
    171             if self._componentValues[idx] is None:
    172                 continue
    173             r = r + '.setComponentByPosition(%s, %r)' % (
    174                 idx, self._componentValues[idx]
    175                 )
    176         return r
    177 
    178     def __eq__(self, other):
    179         return self is other and True or self._componentValues == other
    180     def __ne__(self, other): return self._componentValues != other
    181     def __lt__(self, other): return self._componentValues < other
    182     def __le__(self, other): return self._componentValues <= other
    183     def __gt__(self, other): return self._componentValues > other
    184     def __ge__(self, other): return self._componentValues >= other
    185     if sys.version_info[0] <= 2:
    186         def __nonzero__(self): return bool(self._componentValues)
    187     else:
    188         def __bool__(self): return bool(self._componentValues)
    189 
    190     def getComponentTagMap(self):
    191         raise error.PyAsn1Error('Method not implemented')
    192 
    193     def _cloneComponentValues(self, myClone, cloneValueFlag): pass
    194 
    195     def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None, 
    196               cloneValueFlag=None):
    197         if tagSet is None:
    198             tagSet = self._tagSet
    199         if subtypeSpec is None:
    200             subtypeSpec = self._subtypeSpec
    201         if sizeSpec is None:
    202             sizeSpec = self._sizeSpec
    203         r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
    204         if cloneValueFlag:
    205             self._cloneComponentValues(r, cloneValueFlag)
    206         return r
    207 
    208     def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None,
    209                 sizeSpec=None, cloneValueFlag=None):
    210         if implicitTag is not None:
    211             tagSet = self._tagSet.tagImplicitly(implicitTag)
    212         elif explicitTag is not None:
    213             tagSet = self._tagSet.tagExplicitly(explicitTag)
    214         else:
    215             tagSet = self._tagSet
    216         if subtypeSpec is None:
    217             subtypeSpec = self._subtypeSpec
    218         else:
    219             subtypeSpec = subtypeSpec + self._subtypeSpec
    220         if sizeSpec is None:
    221             sizeSpec = self._sizeSpec
    222         else:
    223             sizeSpec = sizeSpec + self._sizeSpec
    224         r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec)
    225         if cloneValueFlag:
    226             self._cloneComponentValues(r, cloneValueFlag)
    227         return r
    228 
    229     def _verifyComponent(self, idx, value): pass
    230 
    231     def verifySizeSpec(self): self._sizeSpec(self)
    232 
    233     def getComponentByPosition(self, idx):
    234         raise error.PyAsn1Error('Method not implemented')
    235     def setComponentByPosition(self, idx, value, verifyConstraints=True):
    236         raise error.PyAsn1Error('Method not implemented')
    237 
    238     def getComponentType(self): return self._componentType
    239 
    240     def __getitem__(self, idx): return self.getComponentByPosition(idx)
    241     def __setitem__(self, idx, value): self.setComponentByPosition(idx, value)
    242 
    243     def __len__(self): return len(self._componentValues)
    244     
    245     def clear(self):
    246         self._componentValues = []
    247         self._componentValuesSet = 0
    248 
    249     def setDefaultComponents(self): pass
    250