Home | History | Annotate | Download | only in type
      1 # ASN.1 "universal" data types
      2 import operator, sys
      3 from pyasn1.type import base, tag, constraint, namedtype, namedval, tagmap
      4 from pyasn1.codec.ber import eoo
      5 from pyasn1.compat import octets
      6 from pyasn1 import error
      7 
      8 # "Simple" ASN.1 types (yet incomplete)
      9 
     10 class Integer(base.AbstractSimpleAsn1Item):
     11     tagSet = baseTagSet = tag.initTagSet(
     12         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
     13         )
     14     namedValues = namedval.NamedValues()
     15     def __init__(self, value=None, tagSet=None, subtypeSpec=None,
     16                  namedValues=None):
     17         if namedValues is None:
     18             self.__namedValues = self.namedValues
     19         else:
     20             self.__namedValues = namedValues
     21         base.AbstractSimpleAsn1Item.__init__(
     22             self, value, tagSet, subtypeSpec
     23             )
     24 
     25     def __and__(self, value): return self.clone(self._value & value)
     26     def __rand__(self, value): return self.clone(value & self._value)
     27     def __or__(self, value): return self.clone(self._value | value)
     28     def __ror__(self, value): return self.clone(value | self._value)
     29     def __xor__(self, value): return self.clone(self._value ^ value)
     30     def __rxor__(self, value): return self.clone(value ^ self._value)
     31     def __lshift__(self, value): return self.clone(self._value << value)
     32     def __rshift__(self, value): return self.clone(self._value >> value)
     33 
     34     def __add__(self, value): return self.clone(self._value + value)
     35     def __radd__(self, value): return self.clone(value + self._value)
     36     def __sub__(self, value): return self.clone(self._value - value)
     37     def __rsub__(self, value): return self.clone(value - self._value)
     38     def __mul__(self, value): return self.clone(self._value * value)
     39     def __rmul__(self, value): return self.clone(value * self._value)
     40     def __mod__(self, value): return self.clone(self._value % value)
     41     def __rmod__(self, value): return self.clone(value % self._value)
     42     def __pow__(self, value, modulo=None): return self.clone(pow(self._value, value, modulo))
     43     def __rpow__(self, value): return self.clone(pow(value, self._value))
     44 
     45     if sys.version_info[0] <= 2:
     46         def __div__(self, value):  return self.clone(self._value // value)
     47         def __rdiv__(self, value):  return self.clone(value // self._value)
     48     else:
     49         def __truediv__(self, value):  return self.clone(self._value / value)
     50         def __rtruediv__(self, value):  return self.clone(value / self._value)
     51         def __divmod__(self, value):  return self.clone(self._value // value)
     52         def __rdivmod__(self, value):  return self.clone(value // self._value)
     53 
     54         __hash__ = base.AbstractSimpleAsn1Item.__hash__
     55 
     56     def __int__(self): return int(self._value)
     57     if sys.version_info[0] <= 2:
     58         def __long__(self): return long(self._value)
     59     def __float__(self): return float(self._value)    
     60     def __abs__(self): return abs(self._value)
     61     def __index__(self): return int(self._value)
     62 
     63     def __lt__(self, value): return self._value < value
     64     def __le__(self, value): return self._value <= value
     65     def __eq__(self, value): return self._value == value
     66     def __ne__(self, value): return self._value != value
     67     def __gt__(self, value): return self._value > value
     68     def __ge__(self, value): return self._value >= value
     69 
     70     def prettyIn(self, value):
     71         if not isinstance(value, str):
     72             try:
     73                 return int(value)
     74             except:
     75                 raise error.PyAsn1Error(
     76                     'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
     77                     )
     78         r = self.__namedValues.getValue(value)
     79         if r is not None:
     80             return r
     81         try:
     82             return int(value)
     83         except:
     84             raise error.PyAsn1Error(
     85                 'Can\'t coerce %s into integer: %s' % (value, sys.exc_info()[1])
     86                 )
     87 
     88     def prettyOut(self, value):
     89         r = self.__namedValues.getName(value)
     90         return r is None and str(value) or repr(r)
     91 
     92     def getNamedValues(self): return self.__namedValues
     93 
     94     def clone(self, value=None, tagSet=None, subtypeSpec=None,
     95               namedValues=None):
     96         if value is None and tagSet is None and subtypeSpec is None \
     97                and namedValues is None:
     98             return self
     99         if value is None:
    100             value = self._value
    101         if tagSet is None:
    102             tagSet = self._tagSet
    103         if subtypeSpec is None:
    104             subtypeSpec = self._subtypeSpec
    105         if namedValues is None:
    106             namedValues = self.__namedValues
    107         return self.__class__(value, tagSet, subtypeSpec, namedValues)
    108 
    109     def subtype(self, value=None, implicitTag=None, explicitTag=None,
    110                 subtypeSpec=None, namedValues=None):
    111         if value is None:
    112             value = self._value
    113         if implicitTag is not None:
    114             tagSet = self._tagSet.tagImplicitly(implicitTag)
    115         elif explicitTag is not None:
    116             tagSet = self._tagSet.tagExplicitly(explicitTag)
    117         else:
    118             tagSet = self._tagSet
    119         if subtypeSpec is None:
    120             subtypeSpec = self._subtypeSpec
    121         else:
    122             subtypeSpec = subtypeSpec + self._subtypeSpec
    123         if namedValues is None:
    124             namedValues = self.__namedValues
    125         else:
    126             namedValues = namedValues + self.__namedValues
    127         return self.__class__(value, tagSet, subtypeSpec, namedValues)
    128 
    129 class Boolean(Integer):
    130     tagSet = baseTagSet = tag.initTagSet(
    131         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
    132         )
    133     subtypeSpec = Integer.subtypeSpec+constraint.SingleValueConstraint(0,1)
    134     namedValues = Integer.namedValues.clone(('False', 0), ('True', 1))
    135 
    136 class BitString(base.AbstractSimpleAsn1Item):
    137     tagSet = baseTagSet = tag.initTagSet(
    138         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
    139         )
    140     namedValues = namedval.NamedValues()
    141     def __init__(self, value=None, tagSet=None, subtypeSpec=None,
    142                  namedValues=None):
    143         if namedValues is None:
    144             self.__namedValues = self.namedValues
    145         else:
    146             self.__namedValues = namedValues
    147         base.AbstractSimpleAsn1Item.__init__(
    148             self, value, tagSet, subtypeSpec
    149             )
    150 
    151     def clone(self, value=None, tagSet=None, subtypeSpec=None,
    152               namedValues=None):
    153         if value is None and tagSet is None and subtypeSpec is None \
    154                and namedValues is None:
    155             return self
    156         if value is None:
    157             value = self._value
    158         if tagSet is None:
    159             tagSet = self._tagSet
    160         if subtypeSpec is None:
    161             subtypeSpec = self._subtypeSpec
    162         if namedValues is None:
    163             namedValues = self.__namedValues
    164         return self.__class__(value, tagSet, subtypeSpec, namedValues)
    165 
    166     def subtype(self, value=None, implicitTag=None, explicitTag=None,
    167                 subtypeSpec=None, namedValues=None):
    168         if value is None:
    169             value = self._value
    170         if implicitTag is not None:
    171             tagSet = self._tagSet.tagImplicitly(implicitTag)
    172         elif explicitTag is not None:
    173             tagSet = self._tagSet.tagExplicitly(explicitTag)
    174         else:
    175             tagSet = self._tagSet
    176         if subtypeSpec is None:
    177             subtypeSpec = self._subtypeSpec
    178         else:
    179             subtypeSpec = subtypeSpec + self._subtypeSpec
    180         if namedValues is None:
    181             namedValues = self.__namedValues
    182         else:
    183             namedValues = namedValues + self.__namedValues
    184         return self.__class__(value, tagSet, subtypeSpec, namedValues)
    185 
    186     def __str__(self): return str(tuple(self))
    187 
    188     # Immutable sequence object protocol
    189 
    190     def __len__(self):
    191         if self._len is None:
    192             self._len = len(self._value)
    193         return self._len
    194     def __getitem__(self, i):
    195         if isinstance(i, slice):
    196             return self.clone(operator.getitem(self._value, i))
    197         else:
    198             return self._value[i]
    199 
    200     def __add__(self, value): return self.clone(self._value + value)
    201     def __radd__(self, value): return self.clone(value + self._value)
    202     def __mul__(self, value): return self.clone(self._value * value)
    203     def __rmul__(self, value): return self * value
    204 
    205     def prettyIn(self, value):
    206         r = []
    207         if not value:
    208             return ()
    209         elif isinstance(value, str):
    210             if value[0] == '\'':
    211                 if value[-2:] == '\'B':
    212                     for v in value[1:-2]:
    213                         if v == '0':
    214                             r.append(0)
    215                         elif v == '1':
    216                             r.append(1)
    217                         else:
    218                             raise error.PyAsn1Error(
    219                                 'Non-binary BIT STRING initializer %s' % (v,)
    220                                 )
    221                     return tuple(r)
    222                 elif value[-2:] == '\'H':
    223                     for v in value[1:-2]:
    224                         i = 4
    225                         v = int(v, 16)
    226                         while i:
    227                             i = i - 1
    228                             r.append((v>>i)&0x01)
    229                     return tuple(r)
    230                 else:
    231                     raise error.PyAsn1Error(
    232                         'Bad BIT STRING value notation %s' % (value,)
    233                         )                
    234             else:
    235                 for i in value.split(','):
    236                     j = self.__namedValues.getValue(i)
    237                     if j is None:
    238                         raise error.PyAsn1Error(
    239                             'Unknown bit identifier \'%s\'' % (i,)
    240                             )
    241                     if j >= len(r):
    242                         r.extend([0]*(j-len(r)+1))
    243                     r[j] = 1
    244                 return tuple(r)
    245         elif isinstance(value, (tuple, list)):
    246             r = tuple(value)
    247             for b in r:
    248                 if b and b != 1:
    249                     raise error.PyAsn1Error(
    250                         'Non-binary BitString initializer \'%s\'' % (r,)
    251                         )
    252             return r
    253         elif isinstance(value, BitString):
    254             return tuple(value)
    255         else:
    256             raise error.PyAsn1Error(
    257                 'Bad BitString initializer type \'%s\'' % (value,)
    258                 )
    259 
    260     def prettyOut(self, value):
    261         return '\"\'%s\'B\"' % ''.join([str(x) for x in value])
    262 
    263 class OctetString(base.AbstractSimpleAsn1Item):
    264     tagSet = baseTagSet = tag.initTagSet(
    265         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
    266         )
    267     defaultBinValue = defaultHexValue = base.noValue
    268     encoding = 'us-ascii'
    269     def __init__(self, value=None, tagSet=None, subtypeSpec=None,
    270                  encoding=None, binValue=None, hexValue=None):
    271         if encoding is None:
    272             self._encoding = self.encoding
    273         else:
    274             self._encoding = encoding
    275         if binValue is not None:
    276             value = self.fromBinaryString(binValue)
    277         if hexValue is not None:
    278             value = self.fromHexString(hexValue)
    279         if value is None or value is base.noValue:
    280             value = self.defaultHexValue
    281         if value is None or value is base.noValue:
    282             value = self.defaultBinValue
    283         self.__intValue = None
    284         base.AbstractSimpleAsn1Item.__init__(self, value, tagSet, subtypeSpec)
    285 
    286     def clone(self, value=None, tagSet=None, subtypeSpec=None,
    287               encoding=None, binValue=None, hexValue=None):
    288         if value is None and tagSet is None and subtypeSpec is None and \
    289                encoding is None and binValue is None and hexValue is None:
    290             return self
    291         if value is None and binValue is None and hexValue is None:
    292             value = self._value
    293         if tagSet is None:
    294             tagSet = self._tagSet
    295         if subtypeSpec is None:
    296             subtypeSpec = self._subtypeSpec
    297         if encoding is None:
    298             encoding = self._encoding
    299         return self.__class__(
    300             value, tagSet, subtypeSpec, encoding, binValue, hexValue
    301             )
    302    
    303     if sys.version_info[0] <= 2:
    304         def prettyIn(self, value):
    305             if isinstance(value, str):
    306                 return value
    307             elif isinstance(value, (tuple, list)):
    308                 try:
    309                     return ''.join([ chr(x) for x in value ])
    310                 except ValueError:
    311                     raise error.PyAsn1Error(
    312                         'Bad OctetString initializer \'%s\'' % (value,)
    313                         )                
    314             else:
    315                 return str(value)
    316     else:
    317         def prettyIn(self, value):
    318             if isinstance(value, bytes):
    319                 return value
    320             elif isinstance(value, OctetString):
    321                 return value.asOctets()
    322             elif isinstance(value, (tuple, list, map)):
    323                 try:
    324                     return bytes(value)
    325                 except ValueError:
    326                     raise error.PyAsn1Error(
    327                         'Bad OctetString initializer \'%s\'' % (value,)
    328                         )
    329             else:
    330                 try:
    331                     return str(value).encode(self._encoding)
    332                 except UnicodeEncodeError:
    333                     raise error.PyAsn1Error(
    334                         'Can\'t encode string \'%s\' with \'%s\' codec' % (value, self._encoding)
    335                         )
    336                         
    337 
    338     def fromBinaryString(self, value):
    339         bitNo = 8; byte = 0; r = ()
    340         for v in value:
    341             if bitNo:
    342                 bitNo = bitNo - 1
    343             else:
    344                 bitNo = 7
    345                 r = r + (byte,)
    346                 byte = 0
    347             if v == '0':
    348                 v = 0
    349             elif v == '1':
    350                 v = 1
    351             else:
    352                 raise error.PyAsn1Error(
    353                     'Non-binary OCTET STRING initializer %s' % (v,)
    354                     )
    355             byte = byte | (v << bitNo)
    356         return octets.ints2octs(r + (byte,))
    357         
    358     def fromHexString(self, value):            
    359         r = p = ()
    360         for v in value:
    361             if p:
    362                 r = r + (int(p+v, 16),)
    363                 p = ()
    364             else:
    365                 p = v
    366         if p:
    367             r = r + (int(p+'0', 16),)
    368         return octets.ints2octs(r)
    369 
    370     def prettyOut(self, value):
    371         if sys.version_info[0] <= 2:
    372             numbers = tuple([ ord(x) for x in value ])
    373         else:
    374             numbers = tuple(value)
    375         if [ x for x in numbers if x < 32 or x > 126 ]:
    376             return '0x' + ''.join([ '%.2x' % x for x in numbers ])
    377         else:
    378             return str(value)
    379 
    380     def __repr__(self):
    381         if self._value is base.noValue:
    382             return self.__class__.__name__ + '()'
    383         if [ x for x in self.asNumbers() if x < 32 or x > 126 ]:
    384             return self.__class__.__name__ + '(hexValue=\'' + ''.join([ '%.2x' % x for x in self.asNumbers() ])+'\')'
    385         else:
    386             return self.__class__.__name__ + '(\'' + self.prettyOut(self._value) + '\')'
    387                                 
    388     if sys.version_info[0] <= 2:
    389         def __str__(self): return str(self._value)
    390         def __unicode__(self):
    391             return self._value.decode(self._encoding, 'ignore')
    392         def asOctets(self): return self._value
    393         def asNumbers(self):
    394             if self.__intValue is None:
    395                 self.__intValue = tuple([ ord(x) for x in self._value ])
    396             return self.__intValue
    397     else:
    398         def __str__(self): return self._value.decode(self._encoding, 'ignore')
    399         def __bytes__(self): return self._value
    400         def asOctets(self): return self._value
    401         def asNumbers(self):
    402             if self.__intValue is None:
    403                 self.__intValue = tuple(self._value)
    404             return self.__intValue
    405  
    406     # Immutable sequence object protocol
    407     
    408     def __len__(self):
    409         if self._len is None:
    410             self._len = len(self._value)
    411         return self._len
    412     def __getitem__(self, i):
    413         if isinstance(i, slice):
    414             return self.clone(operator.getitem(self._value, i))
    415         else:
    416             return self._value[i]
    417 
    418     def __add__(self, value): return self.clone(self._value + self.prettyIn(value))
    419     def __radd__(self, value): return self.clone(self.prettyIn(value) + self._value)
    420     def __mul__(self, value): return self.clone(self._value * value)
    421     def __rmul__(self, value): return self * value
    422 
    423 class Null(OctetString):
    424     defaultValue = ''.encode()  # This is tightly constrained
    425     tagSet = baseTagSet = tag.initTagSet(
    426         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
    427         )
    428     subtypeSpec = OctetString.subtypeSpec+constraint.SingleValueConstraint(''.encode())
    429     
    430 if sys.version_info[0] <= 2:
    431     intTypes = (int, long)
    432 else:
    433     intTypes = int
    434 
    435 class ObjectIdentifier(base.AbstractSimpleAsn1Item):
    436     tagSet = baseTagSet = tag.initTagSet(
    437         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
    438         )
    439     def __add__(self, other): return self.clone(self._value + other)
    440     def __radd__(self, other): return self.clone(other + self._value)
    441 
    442     def asTuple(self): return self._value
    443     
    444     # Sequence object protocol
    445     
    446     def __len__(self):
    447         if self._len is None:
    448             self._len = len(self._value)
    449         return self._len
    450     def __getitem__(self, i):
    451         if isinstance(i, slice):
    452             return self.clone(
    453                 operator.getitem(self._value, i)
    454                 )
    455         else:
    456             return self._value[i]
    457 
    458     def __str__(self): return self.prettyPrint()
    459     
    460     def index(self, suboid): return self._value.index(suboid)
    461 
    462     def isPrefixOf(self, value):
    463         """Returns true if argument OID resides deeper in the OID tree"""
    464         l = len(self)
    465         if l <= len(value):
    466             if self._value[:l] == value[:l]:
    467                 return 1
    468         return 0
    469 
    470     def prettyIn(self, value):
    471         """Dotted -> tuple of numerics OID converter"""
    472         if isinstance(value, tuple):
    473             pass
    474         elif isinstance(value, ObjectIdentifier):
    475             return tuple(value)        
    476         elif isinstance(value, str):
    477             r = []
    478             for element in [ x for x in value.split('.') if x != '' ]:
    479                 try:
    480                     r.append(int(element, 0))
    481                 except ValueError:
    482                     raise error.PyAsn1Error(
    483                         'Malformed Object ID %s at %s: %s' %
    484                         (str(value), self.__class__.__name__, sys.exc_info()[1])
    485                         )
    486             value = tuple(r)
    487         else:
    488             try:
    489                 value = tuple(value)
    490             except TypeError:
    491                 raise error.PyAsn1Error(
    492                         'Malformed Object ID %s at %s: %s' %
    493                         (str(value), self.__class__.__name__,sys.exc_info()[1])
    494                         )
    495 
    496         for x in value:
    497             if not isinstance(x, intTypes) or x < 0:
    498                 raise error.PyAsn1Error(
    499                     'Invalid sub-ID in %s at %s' % (value, self.__class__.__name__)
    500                     )
    501     
    502         return value
    503 
    504     def prettyOut(self, value): return '.'.join([ str(x) for x in value ])
    505     
    506 class Real(base.AbstractSimpleAsn1Item):
    507     try:
    508         _plusInf = float('inf')
    509         _minusInf = float('-inf')
    510         _inf = (_plusInf, _minusInf)
    511     except ValueError:
    512         # Infinity support is platform and Python dependent
    513         _plusInf = _minusInf = None
    514         _inf = ()
    515 
    516     tagSet = baseTagSet = tag.initTagSet(
    517         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
    518         )
    519 
    520     def __normalizeBase10(self, value):
    521         m, b, e = value
    522         while m and m % 10 == 0:
    523             m = m / 10
    524             e = e + 1
    525         return m, b, e
    526 
    527     def prettyIn(self, value):
    528         if isinstance(value, tuple) and len(value) == 3:
    529             for d in value:
    530                 if not isinstance(d, intTypes):
    531                     raise error.PyAsn1Error(
    532                         'Lame Real value syntax: %s' % (value,)
    533                         )
    534             if value[1] not in (2, 10):
    535                 raise error.PyAsn1Error(
    536                     'Prohibited base for Real value: %s' % (value[1],)
    537                     )
    538             if value[1] == 10:
    539                 value = self.__normalizeBase10(value)
    540             return value
    541         elif isinstance(value, intTypes):
    542             return self.__normalizeBase10((value, 10, 0))
    543         elif isinstance(value, float):
    544             if self._inf and value in self._inf:
    545                 return value
    546             else:
    547                 e = 0
    548                 while int(value) != value:
    549                     value = value * 10
    550                     e = e - 1
    551                 return self.__normalizeBase10((int(value), 10, e))
    552         elif isinstance(value, Real):
    553             return tuple(value)
    554         elif isinstance(value, str):  # handle infinite literal
    555             try:
    556                 return float(value)
    557             except ValueError:
    558                 pass
    559         raise error.PyAsn1Error(
    560             'Bad real value syntax: %s' % (value,)
    561             )
    562         
    563     def prettyOut(self, value):
    564         if value in self._inf:
    565             return '\'%s\'' % value
    566         else:
    567             return str(value)
    568 
    569     def isPlusInfinity(self): return self._value == self._plusInf
    570     def isMinusInfinity(self): return self._value == self._minusInf
    571     def isInfinity(self): return self._value in self._inf
    572     
    573     def __str__(self): return str(float(self))
    574     
    575     def __add__(self, value): return self.clone(float(self) + value)
    576     def __radd__(self, value): return self + value
    577     def __mul__(self, value): return self.clone(float(self) * value)
    578     def __rmul__(self, value): return self * value
    579     def __sub__(self, value): return self.clone(float(self) - value)
    580     def __rsub__(self, value): return self.clone(value - float(self))
    581     def __mod__(self, value): return self.clone(float(self) % value)
    582     def __rmod__(self, value): return self.clone(value % float(self))
    583     def __pow__(self, value, modulo=None): return self.clone(pow(float(self), value, modulo))
    584     def __rpow__(self, value): return self.clone(pow(value, float(self)))
    585 
    586     if sys.version_info[0] <= 2:
    587         def __div__(self, value): return self.clone(float(self) / value)
    588         def __rdiv__(self, value): return self.clone(value / float(self))
    589     else:
    590         def __truediv__(self, value): return self.clone(float(self) / value)
    591         def __rtruediv__(self, value): return self.clone(value / float(self))
    592         def __divmod__(self, value): return self.clone(float(self) // value)
    593         def __rdivmod__(self, value): return self.clone(value // float(self))
    594 
    595     def __int__(self): return int(float(self))
    596     if sys.version_info[0] <= 2:
    597         def __long__(self): return long(float(self))
    598     def __float__(self):
    599         if self._value in self._inf:
    600             return self._value
    601         else:
    602             return float(
    603                 self._value[0] * pow(self._value[1], self._value[2])
    604                 )
    605     def __abs__(self): return abs(float(self))
    606 
    607     def __lt__(self, value): return float(self) < value
    608     def __le__(self, value): return float(self) <= value
    609     def __eq__(self, value): return float(self) == value
    610     def __ne__(self, value): return float(self) != value
    611     def __gt__(self, value): return float(self) > value
    612     def __ge__(self, value): return float(self) >= value
    613 
    614     if sys.version_info[0] <= 2:
    615         def __nonzero__(self): return bool(float(self))
    616     else:
    617         def __bool__(self): return bool(float(self))
    618         __hash__ = base.AbstractSimpleAsn1Item.__hash__
    619 
    620     def __getitem__(self, idx):
    621         if self._value in self._inf:
    622             raise error.PyAsn1Error('Invalid infinite value operation')
    623         else:
    624             return self._value[idx]
    625     
    626 class Enumerated(Integer):
    627     tagSet = baseTagSet = tag.initTagSet(
    628         tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
    629         )
    630 
    631 # "Structured" ASN.1 types
    632 
    633 class SetOf(base.AbstractConstructedAsn1Item):
    634     componentType = None
    635     tagSet = baseTagSet = tag.initTagSet(
    636         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
    637         )
    638     typeId = 1
    639 
    640     def _cloneComponentValues(self, myClone, cloneValueFlag):
    641         idx = 0; l = len(self._componentValues)
    642         while idx < l:
    643             c = self._componentValues[idx]
    644             if c is not None:
    645                 if isinstance(c, base.AbstractConstructedAsn1Item):
    646                     myClone.setComponentByPosition(
    647                         idx, c.clone(cloneValueFlag=cloneValueFlag)
    648                         )
    649                 else:
    650                     myClone.setComponentByPosition(idx, c.clone())
    651             idx = idx + 1
    652         
    653     def _verifyComponent(self, idx, value):
    654         if self._componentType is not None and \
    655                not self._componentType.isSuperTypeOf(value):
    656             raise error.PyAsn1Error('Component type error %s' % (value,))
    657 
    658     def getComponentByPosition(self, idx): return self._componentValues[idx]
    659     def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
    660         l = len(self._componentValues)
    661         if idx >= l:
    662             self._componentValues = self._componentValues + (idx-l+1)*[None]
    663         if value is None:
    664             if self._componentValues[idx] is None:
    665                 if self._componentType is None:
    666                     raise error.PyAsn1Error('Component type not defined')
    667                 self._componentValues[idx] = self._componentType.clone()
    668                 self._componentValuesSet = self._componentValuesSet + 1
    669             return self
    670         elif not isinstance(value, base.Asn1Item):
    671             if self._componentType is None:
    672                 raise error.PyAsn1Error('Component type not defined')
    673             if isinstance(self._componentType, base.AbstractSimpleAsn1Item):
    674                 value = self._componentType.clone(value=value)
    675             else:
    676                 raise error.PyAsn1Error('Instance value required')
    677         if verifyConstraints:
    678             if self._componentType is not None:
    679                 self._verifyComponent(idx, value)
    680             self._verifySubtypeSpec(value, idx)            
    681         if self._componentValues[idx] is None:
    682             self._componentValuesSet = self._componentValuesSet + 1
    683         self._componentValues[idx] = value
    684         return self
    685 
    686     def getComponentTagMap(self):
    687         if self._componentType is not None:
    688             return self._componentType.getTagMap()
    689 
    690     def prettyPrint(self, scope=0):
    691         scope = scope + 1
    692         r = self.__class__.__name__ + ':\n'        
    693         for idx in range(len(self._componentValues)):
    694             r = r + ' '*scope
    695             if self._componentValues[idx] is None:
    696                 r = r + '<empty>'
    697             else:
    698                 r = r + self._componentValues[idx].prettyPrint(scope)
    699         return r
    700 
    701 class SequenceOf(SetOf):
    702     tagSet = baseTagSet = tag.initTagSet(
    703         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
    704         )
    705     typeId = 2
    706 
    707 class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
    708     componentType = namedtype.NamedTypes()
    709     def __init__(self, componentType=None, tagSet=None,
    710                  subtypeSpec=None, sizeSpec=None):
    711         base.AbstractConstructedAsn1Item.__init__(
    712             self, componentType, tagSet, subtypeSpec, sizeSpec
    713             )
    714         if self._componentType is None:
    715             self._componentTypeLen = 0
    716         else:
    717             self._componentTypeLen = len(self._componentType)
    718 
    719     def __getitem__(self, idx):
    720         if isinstance(idx, str):
    721             return self.getComponentByName(idx)
    722         else:
    723             return base.AbstractConstructedAsn1Item.__getitem__(self, idx)
    724 
    725     def __setitem__(self, idx, value):
    726         if isinstance(idx, str):
    727             self.setComponentByName(idx, value)
    728         else:
    729             base.AbstractConstructedAsn1Item.__setitem__(self, idx, value)
    730         
    731     def _cloneComponentValues(self, myClone, cloneValueFlag):
    732         idx = 0; l = len(self._componentValues)
    733         while idx < l:
    734             c = self._componentValues[idx]
    735             if c is not None:
    736                 if isinstance(c, base.AbstractConstructedAsn1Item):
    737                     myClone.setComponentByPosition(
    738                         idx, c.clone(cloneValueFlag=cloneValueFlag)
    739                         )
    740                 else:
    741                     myClone.setComponentByPosition(idx, c.clone())
    742             idx = idx + 1
    743 
    744     def _verifyComponent(self, idx, value):
    745         if idx >= self._componentTypeLen:
    746             raise error.PyAsn1Error(
    747                 'Component type error out of range'
    748                 )
    749         t = self._componentType[idx].getType()
    750         if not t.isSuperTypeOf(value):
    751             raise error.PyAsn1Error('Component type error %r vs %r' % (t, value))
    752 
    753     def getComponentByName(self, name):
    754         return self.getComponentByPosition(
    755             self._componentType.getPositionByName(name)
    756             )
    757     def setComponentByName(self, name, value=None, verifyConstraints=True):
    758         return self.setComponentByPosition(
    759             self._componentType.getPositionByName(name), value,
    760             verifyConstraints
    761             )
    762 
    763     def getComponentByPosition(self, idx):
    764         try:
    765             return self._componentValues[idx]
    766         except IndexError:
    767             if idx < self._componentTypeLen:
    768                 return
    769             raise
    770     def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
    771         l = len(self._componentValues)
    772         if idx >= l:
    773             self._componentValues = self._componentValues + (idx-l+1)*[None]
    774         if value is None:
    775             if self._componentValues[idx] is None:
    776                 self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
    777                 self._componentValuesSet = self._componentValuesSet + 1
    778             return self
    779         elif not isinstance(value, base.Asn1Item):
    780             t = self._componentType.getTypeByPosition(idx)
    781             if isinstance(t, base.AbstractSimpleAsn1Item):
    782                 value = t.clone(value=value)
    783             else:
    784                 raise error.PyAsn1Error('Instance value required')
    785         if verifyConstraints:
    786             if self._componentTypeLen:
    787                 self._verifyComponent(idx, value)
    788             self._verifySubtypeSpec(value, idx)            
    789         if self._componentValues[idx] is None:
    790             self._componentValuesSet = self._componentValuesSet + 1
    791         self._componentValues[idx] = value
    792         return self
    793 
    794     def getNameByPosition(self, idx):
    795         if self._componentTypeLen:
    796             return self._componentType.getNameByPosition(idx)
    797 
    798     def getDefaultComponentByPosition(self, idx):
    799         if self._componentTypeLen and self._componentType[idx].isDefaulted:
    800             return self._componentType[idx].getType()
    801 
    802     def getComponentType(self):
    803         if self._componentTypeLen:
    804             return self._componentType
    805     
    806     def setDefaultComponents(self):
    807         if self._componentTypeLen == self._componentValuesSet:
    808             return
    809         idx = self._componentTypeLen
    810         while idx:
    811             idx = idx - 1
    812             if self._componentType[idx].isDefaulted:
    813                 if self.getComponentByPosition(idx) is None:
    814                     self.setComponentByPosition(idx)
    815             elif not self._componentType[idx].isOptional:
    816                 if self.getComponentByPosition(idx) is None:
    817                     raise error.PyAsn1Error(
    818                         'Uninitialized component #%s at %r' % (idx, self)
    819                         )
    820 
    821     def prettyPrint(self, scope=0):
    822         scope = scope + 1
    823         r = self.__class__.__name__ + ':\n'
    824         for idx in range(len(self._componentValues)):
    825             if self._componentValues[idx] is not None:
    826                 r = r + ' '*scope
    827                 componentType = self.getComponentType()
    828                 if componentType is None:
    829                     r = r + '<no-name>'
    830                 else:
    831                     r = r + componentType.getNameByPosition(idx)
    832                 r = '%s=%s\n' % (
    833                     r, self._componentValues[idx].prettyPrint(scope)
    834                     )
    835         return r
    836 
    837 class Sequence(SequenceAndSetBase):
    838     tagSet = baseTagSet = tag.initTagSet(
    839         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
    840         )
    841     typeId = 3
    842 
    843     def getComponentTagMapNearPosition(self, idx):
    844         if self._componentType:
    845             return self._componentType.getTagMapNearPosition(idx)
    846     
    847     def getComponentPositionNearType(self, tagSet, idx):
    848         if self._componentType:
    849             return self._componentType.getPositionNearType(tagSet, idx)
    850         else:
    851             return idx
    852     
    853 class Set(SequenceAndSetBase):
    854     tagSet = baseTagSet = tag.initTagSet(
    855         tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
    856         )
    857     typeId = 4
    858 
    859     def getComponent(self, innerFlag=0): return self
    860     
    861     def getComponentByType(self, tagSet, innerFlag=0):
    862         c = self.getComponentByPosition(
    863             self._componentType.getPositionByType(tagSet)
    864             )
    865         if innerFlag and isinstance(c, Set):
    866             # get inner component by inner tagSet
    867             return c.getComponent(1)
    868         else:
    869             # get outer component by inner tagSet
    870             return c
    871         
    872     def setComponentByType(self, tagSet, value=None, innerFlag=0,
    873                            verifyConstraints=True):
    874         idx = self._componentType.getPositionByType(tagSet)
    875         t = self._componentType.getTypeByPosition(idx)
    876         if innerFlag:  # set inner component by inner tagSet
    877             if t.getTagSet():
    878                 return self.setComponentByPosition(
    879                     idx, value, verifyConstraints
    880                     )
    881             else:
    882                 t = self.setComponentByPosition(idx).getComponentByPosition(idx)
    883                 return t.setComponentByType(
    884                     tagSet, value, innerFlag, verifyConstraints
    885                     )
    886         else:  # set outer component by inner tagSet
    887             return self.setComponentByPosition(
    888                 idx, value, verifyConstraints
    889                 )
    890             
    891     def getComponentTagMap(self):
    892         if self._componentType:
    893             return self._componentType.getTagMap(True)
    894 
    895     def getComponentPositionByType(self, tagSet):
    896         if self._componentType:
    897             return self._componentType.getPositionByType(tagSet)
    898 
    899 class Choice(Set):
    900     tagSet = baseTagSet = tag.TagSet()  # untagged
    901     sizeSpec = constraint.ConstraintsIntersection(
    902         constraint.ValueSizeConstraint(1, 1)
    903         )
    904     typeId = 5
    905     _currentIdx = None
    906 
    907     def __eq__(self, other):
    908         if self._componentValues:
    909             return self._componentValues[self._currentIdx] == other
    910         return NotImplemented
    911     def __ne__(self, other):
    912         if self._componentValues:
    913             return self._componentValues[self._currentIdx] != other
    914         return NotImplemented
    915     def __lt__(self, other):
    916         if self._componentValues:
    917             return self._componentValues[self._currentIdx] < other
    918         return NotImplemented
    919     def __le__(self, other):
    920         if self._componentValues:
    921             return self._componentValues[self._currentIdx] <= other
    922         return NotImplemented
    923     def __gt__(self, other):
    924         if self._componentValues:
    925             return self._componentValues[self._currentIdx] > other
    926         return NotImplemented
    927     def __ge__(self, other):
    928         if self._componentValues:
    929             return self._componentValues[self._currentIdx] >= other
    930         return NotImplemented
    931     if sys.version_info[0] <= 2:
    932         def __nonzero__(self): return bool(self._componentValues)
    933     else:
    934         def __bool__(self): return bool(self._componentValues)
    935 
    936     def __len__(self): return self._currentIdx is not None and 1 or 0
    937     
    938     def verifySizeSpec(self):
    939         if self._currentIdx is None:
    940             raise error.PyAsn1Error('Component not chosen')
    941         else:
    942             self._sizeSpec(' ')
    943 
    944     def _cloneComponentValues(self, myClone, cloneValueFlag):
    945         try:
    946             c = self.getComponent()
    947         except error.PyAsn1Error:
    948             pass
    949         else:
    950             if isinstance(c, Choice):
    951                 tagSet = c.getEffectiveTagSet()
    952             else:
    953                 tagSet = c.getTagSet()
    954             if isinstance(c, base.AbstractConstructedAsn1Item):
    955                 myClone.setComponentByType(
    956                     tagSet, c.clone(cloneValueFlag=cloneValueFlag)
    957                     )
    958             else:
    959                 myClone.setComponentByType(tagSet, c.clone())
    960 
    961     def setComponentByPosition(self, idx, value=None, verifyConstraints=True):
    962         l = len(self._componentValues)
    963         if idx >= l:
    964             self._componentValues = self._componentValues + (idx-l+1)*[None]
    965         if self._currentIdx is not None:
    966             self._componentValues[self._currentIdx] = None
    967         if value is None:
    968             if self._componentValues[idx] is None:
    969                 self._componentValues[idx] = self._componentType.getTypeByPosition(idx).clone()
    970                 self._componentValuesSet = 1
    971                 self._currentIdx = idx
    972             return self
    973         elif not isinstance(value, base.Asn1Item):
    974             value = self._componentType.getTypeByPosition(idx).clone(
    975                 value=value
    976                 )
    977         if verifyConstraints:
    978             if self._componentTypeLen:
    979                 self._verifyComponent(idx, value)
    980             self._verifySubtypeSpec(value, idx)            
    981         self._componentValues[idx] = value
    982         self._currentIdx = idx
    983         self._componentValuesSet = 1
    984         return self
    985 
    986     def getMinTagSet(self):
    987         if self._tagSet:
    988             return self._tagSet
    989         else:
    990             return self._componentType.genMinTagSet()
    991 
    992     def getEffectiveTagSet(self):
    993         if self._tagSet:
    994             return self._tagSet
    995         else:
    996             c = self.getComponent()
    997             if isinstance(c, Choice):
    998                 return c.getEffectiveTagSet()
    999             else:
   1000                 return c.getTagSet()
   1001 
   1002     def getTagMap(self):
   1003         if self._tagSet:
   1004             return Set.getTagMap(self)
   1005         else:
   1006             return Set.getComponentTagMap(self)
   1007 
   1008     def getComponent(self, innerFlag=0):
   1009         if self._currentIdx is None:
   1010             raise error.PyAsn1Error('Component not chosen')
   1011         else:
   1012             c = self._componentValues[self._currentIdx]
   1013             if innerFlag and isinstance(c, Choice):
   1014                 return c.getComponent(innerFlag)
   1015             else:
   1016                 return c
   1017 
   1018     def getName(self, innerFlag=0):
   1019         if self._currentIdx is None:
   1020             raise error.PyAsn1Error('Component not chosen')
   1021         else:
   1022             if innerFlag:
   1023                 c = self._componentValues[self._currentIdx]
   1024                 if isinstance(c, Choice):
   1025                     return c.getName(innerFlag)
   1026             return self._componentType.getNameByPosition(self._currentIdx)
   1027 
   1028     def setDefaultComponents(self): pass
   1029 
   1030 class Any(OctetString):
   1031     tagSet = baseTagSet = tag.TagSet()  # untagged
   1032     typeId = 6
   1033 
   1034     def getTagMap(self):
   1035         return tagmap.TagMap(
   1036             { self.getTagSet(): self },
   1037             { eoo.endOfOctets.getTagSet(): eoo.endOfOctets },
   1038             self
   1039             )
   1040 
   1041 # XXX
   1042 # coercion rules?
   1043