1# ASN.1 "universal" data types
2import operator, sys
3from pyasn1.type import base, tag, constraint, namedtype, namedval, tagmap
4from pyasn1.codec.ber import eoo
5from pyasn1.compat import octets
6from pyasn1 import error
7
8# "Simple" ASN.1 types (yet incomplete)
9
10class 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
129class 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
136class 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
263class 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
423class 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
430if sys.version_info[0] <= 2:
431    intTypes = (int, long)
432else:
433    intTypes = int
434
435class 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
506class 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
626class Enumerated(Integer):
627    tagSet = baseTagSet = tag.initTagSet(
628        tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
629        )
630
631# "Structured" ASN.1 types
632
633class 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
701class SequenceOf(SetOf):
702    tagSet = baseTagSet = tag.initTagSet(
703        tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
704        )
705    typeId = 2
706
707class 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
837class 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
853class 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
899class 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
1030class 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