707 lines
22 KiB
Python
707 lines
22 KiB
Python
#
|
|
# This file is part of pyasn1 software.
|
|
#
|
|
# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
|
|
# License: https://pyasn1.readthedocs.io/en/latest/license.html
|
|
#
|
|
import sys
|
|
|
|
from pyasn1 import error
|
|
from pyasn1.type import constraint
|
|
from pyasn1.type import tag
|
|
from pyasn1.type import tagmap
|
|
|
|
__all__ = ['Asn1Item', 'Asn1Type', 'SimpleAsn1Type',
|
|
'ConstructedAsn1Type']
|
|
|
|
|
|
class Asn1Item(object):
|
|
@classmethod
|
|
def getTypeId(cls, increment=1):
|
|
try:
|
|
Asn1Item._typeCounter += increment
|
|
except AttributeError:
|
|
Asn1Item._typeCounter = increment
|
|
return Asn1Item._typeCounter
|
|
|
|
|
|
class Asn1Type(Asn1Item):
|
|
"""Base class for all classes representing ASN.1 types.
|
|
|
|
In the user code, |ASN.1| class is normally used only for telling
|
|
ASN.1 objects from others.
|
|
|
|
Note
|
|
----
|
|
For as long as ASN.1 is concerned, a way to compare ASN.1 types
|
|
is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
|
|
"""
|
|
#: Set or return a :py:class:`~pyasn1.type.tag.TagSet` object representing
|
|
#: ASN.1 tag(s) associated with |ASN.1| type.
|
|
tagSet = tag.TagSet()
|
|
|
|
#: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
|
|
#: object imposing constraints on initialization values.
|
|
subtypeSpec = constraint.ConstraintsIntersection()
|
|
|
|
# Disambiguation ASN.1 types identification
|
|
typeId = None
|
|
|
|
def __init__(self, **kwargs):
|
|
readOnly = {
|
|
'tagSet': self.tagSet,
|
|
'subtypeSpec': self.subtypeSpec
|
|
}
|
|
|
|
readOnly.update(kwargs)
|
|
|
|
self.__dict__.update(readOnly)
|
|
|
|
self._readOnly = readOnly
|
|
|
|
def __setattr__(self, name, value):
|
|
if name[0] != '_' and name in self._readOnly:
|
|
raise error.PyAsn1Error('read-only instance attribute "%s"' % name)
|
|
|
|
self.__dict__[name] = value
|
|
|
|
def __str__(self):
|
|
return self.prettyPrint()
|
|
|
|
@property
|
|
def readOnly(self):
|
|
return self._readOnly
|
|
|
|
@property
|
|
def effectiveTagSet(self):
|
|
"""For |ASN.1| type is equivalent to *tagSet*
|
|
"""
|
|
return self.tagSet # used by untagged types
|
|
|
|
@property
|
|
def tagMap(self):
|
|
"""Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping ASN.1 tags to ASN.1 objects within callee object.
|
|
"""
|
|
return tagmap.TagMap({self.tagSet: self})
|
|
|
|
def isSameTypeWith(self, other, matchTags=True, matchConstraints=True):
|
|
"""Examine |ASN.1| type for equality with other ASN.1 type.
|
|
|
|
ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
|
|
(:py:mod:`~pyasn1.type.constraint`) are examined when carrying
|
|
out ASN.1 types comparison.
|
|
|
|
Python class inheritance relationship is NOT considered.
|
|
|
|
Parameters
|
|
----------
|
|
other: a pyasn1 type object
|
|
Class instance representing ASN.1 type.
|
|
|
|
Returns
|
|
-------
|
|
: :class:`bool`
|
|
:obj:`True` if *other* is |ASN.1| type,
|
|
:obj:`False` otherwise.
|
|
"""
|
|
return (self is other or
|
|
(not matchTags or self.tagSet == other.tagSet) and
|
|
(not matchConstraints or self.subtypeSpec == other.subtypeSpec))
|
|
|
|
def isSuperTypeOf(self, other, matchTags=True, matchConstraints=True):
|
|
"""Examine |ASN.1| type for subtype relationship with other ASN.1 type.
|
|
|
|
ASN.1 tags (:py:mod:`~pyasn1.type.tag`) and constraints
|
|
(:py:mod:`~pyasn1.type.constraint`) are examined when carrying
|
|
out ASN.1 types comparison.
|
|
|
|
Python class inheritance relationship is NOT considered.
|
|
|
|
Parameters
|
|
----------
|
|
other: a pyasn1 type object
|
|
Class instance representing ASN.1 type.
|
|
|
|
Returns
|
|
-------
|
|
: :class:`bool`
|
|
:obj:`True` if *other* is a subtype of |ASN.1| type,
|
|
:obj:`False` otherwise.
|
|
"""
|
|
return (not matchTags or
|
|
(self.tagSet.isSuperTagSetOf(other.tagSet)) and
|
|
(not matchConstraints or self.subtypeSpec.isSuperTypeOf(other.subtypeSpec)))
|
|
|
|
@staticmethod
|
|
def isNoValue(*values):
|
|
for value in values:
|
|
if value is not noValue:
|
|
return False
|
|
return True
|
|
|
|
def prettyPrint(self, scope=0):
|
|
raise NotImplementedError()
|
|
|
|
# backward compatibility
|
|
|
|
def getTagSet(self):
|
|
return self.tagSet
|
|
|
|
def getEffectiveTagSet(self):
|
|
return self.effectiveTagSet
|
|
|
|
def getTagMap(self):
|
|
return self.tagMap
|
|
|
|
def getSubtypeSpec(self):
|
|
return self.subtypeSpec
|
|
|
|
# backward compatibility
|
|
def hasValue(self):
|
|
return self.isValue
|
|
|
|
# Backward compatibility
|
|
Asn1ItemBase = Asn1Type
|
|
|
|
|
|
class NoValue(object):
|
|
"""Create a singleton instance of NoValue class.
|
|
|
|
The *NoValue* sentinel object represents an instance of ASN.1 schema
|
|
object as opposed to ASN.1 value object.
|
|
|
|
Only ASN.1 schema-related operations can be performed on ASN.1
|
|
schema objects.
|
|
|
|
Warning
|
|
-------
|
|
Any operation attempted on the *noValue* object will raise the
|
|
*PyAsn1Error* exception.
|
|
"""
|
|
skipMethods = {
|
|
'__slots__',
|
|
# attributes
|
|
'__getattribute__',
|
|
'__getattr__',
|
|
'__setattr__',
|
|
'__delattr__',
|
|
# class instance
|
|
'__class__',
|
|
'__init__',
|
|
'__del__',
|
|
'__new__',
|
|
'__repr__',
|
|
'__qualname__',
|
|
'__objclass__',
|
|
'im_class',
|
|
'__sizeof__',
|
|
# pickle protocol
|
|
'__reduce__',
|
|
'__reduce_ex__',
|
|
'__getnewargs__',
|
|
'__getinitargs__',
|
|
'__getstate__',
|
|
'__setstate__',
|
|
}
|
|
|
|
_instance = None
|
|
|
|
def __new__(cls):
|
|
if cls._instance is None:
|
|
def getPlug(name):
|
|
def plug(self, *args, **kw):
|
|
raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % name)
|
|
return plug
|
|
|
|
op_names = [name
|
|
for typ in (str, int, list, dict)
|
|
for name in dir(typ)
|
|
if (name not in cls.skipMethods and
|
|
name.startswith('__') and
|
|
name.endswith('__') and
|
|
callable(getattr(typ, name)))]
|
|
|
|
for name in set(op_names):
|
|
setattr(cls, name, getPlug(name))
|
|
|
|
cls._instance = object.__new__(cls)
|
|
|
|
return cls._instance
|
|
|
|
def __getattr__(self, attr):
|
|
if attr in self.skipMethods:
|
|
raise AttributeError('Attribute %s not present' % attr)
|
|
|
|
raise error.PyAsn1Error('Attempted "%s" operation on ASN.1 schema object' % attr)
|
|
|
|
def __repr__(self):
|
|
return '<%s object>' % self.__class__.__name__
|
|
|
|
|
|
noValue = NoValue()
|
|
|
|
|
|
class SimpleAsn1Type(Asn1Type):
|
|
"""Base class for all simple classes representing ASN.1 types.
|
|
|
|
ASN.1 distinguishes types by their ability to hold other objects.
|
|
Scalar types are known as *simple* in ASN.1.
|
|
|
|
In the user code, |ASN.1| class is normally used only for telling
|
|
ASN.1 objects from others.
|
|
|
|
Note
|
|
----
|
|
For as long as ASN.1 is concerned, a way to compare ASN.1 types
|
|
is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
|
|
"""
|
|
#: Default payload value
|
|
defaultValue = noValue
|
|
|
|
def __init__(self, value=noValue, **kwargs):
|
|
Asn1Type.__init__(self, **kwargs)
|
|
if value is noValue:
|
|
value = self.defaultValue
|
|
else:
|
|
value = self.prettyIn(value)
|
|
try:
|
|
self.subtypeSpec(value)
|
|
|
|
except error.PyAsn1Error:
|
|
exType, exValue, exTb = sys.exc_info()
|
|
raise exType('%s at %s' % (exValue, self.__class__.__name__))
|
|
|
|
self._value = value
|
|
|
|
def __repr__(self):
|
|
representation = '%s %s object' % (
|
|
self.__class__.__name__, self.isValue and 'value' or 'schema')
|
|
|
|
for attr, value in self.readOnly.items():
|
|
if value:
|
|
representation += ', %s %s' % (attr, value)
|
|
|
|
if self.isValue:
|
|
value = self.prettyPrint()
|
|
if len(value) > 32:
|
|
value = value[:16] + '...' + value[-16:]
|
|
representation += ', payload [%s]' % value
|
|
|
|
return '<%s>' % representation
|
|
|
|
def __eq__(self, other):
|
|
return self is other and True or self._value == other
|
|
|
|
def __ne__(self, other):
|
|
return self._value != other
|
|
|
|
def __lt__(self, other):
|
|
return self._value < other
|
|
|
|
def __le__(self, other):
|
|
return self._value <= other
|
|
|
|
def __gt__(self, other):
|
|
return self._value > other
|
|
|
|
def __ge__(self, other):
|
|
return self._value >= other
|
|
|
|
if sys.version_info[0] <= 2:
|
|
def __nonzero__(self):
|
|
return self._value and True or False
|
|
else:
|
|
def __bool__(self):
|
|
return self._value and True or False
|
|
|
|
def __hash__(self):
|
|
return hash(self._value)
|
|
|
|
@property
|
|
def isValue(self):
|
|
"""Indicate that |ASN.1| object represents ASN.1 value.
|
|
|
|
If *isValue* is :obj:`False` then this object represents just
|
|
ASN.1 schema.
|
|
|
|
If *isValue* is :obj:`True` then, in addition to its ASN.1 schema
|
|
features, this object can also be used like a Python built-in object
|
|
(e.g. :class:`int`, :class:`str`, :class:`dict` etc.).
|
|
|
|
Returns
|
|
-------
|
|
: :class:`bool`
|
|
:obj:`False` if object represents just ASN.1 schema.
|
|
:obj:`True` if object represents ASN.1 schema and can be used as a normal value.
|
|
|
|
Note
|
|
----
|
|
There is an important distinction between PyASN1 schema and value objects.
|
|
The PyASN1 schema objects can only participate in ASN.1 schema-related
|
|
operations (e.g. defining or testing the structure of the data). Most
|
|
obvious uses of ASN.1 schema is to guide serialisation codecs whilst
|
|
encoding/decoding serialised ASN.1 contents.
|
|
|
|
The PyASN1 value objects can **additionally** participate in many operations
|
|
involving regular Python objects (e.g. arithmetic, comprehension etc).
|
|
"""
|
|
return self._value is not noValue
|
|
|
|
def clone(self, value=noValue, **kwargs):
|
|
"""Create a modified version of |ASN.1| schema or value object.
|
|
|
|
The `clone()` method accepts the same set arguments as |ASN.1|
|
|
class takes on instantiation except that all arguments
|
|
of the `clone()` method are optional.
|
|
|
|
Whatever arguments are supplied, they are used to create a copy
|
|
of `self` taking precedence over the ones used to instantiate `self`.
|
|
|
|
Note
|
|
----
|
|
Due to the immutable nature of the |ASN.1| object, if no arguments
|
|
are supplied, no new |ASN.1| object will be created and `self` will
|
|
be returned instead.
|
|
"""
|
|
if value is noValue:
|
|
if not kwargs:
|
|
return self
|
|
|
|
value = self._value
|
|
|
|
initializers = self.readOnly.copy()
|
|
initializers.update(kwargs)
|
|
|
|
return self.__class__(value, **initializers)
|
|
|
|
def subtype(self, value=noValue, **kwargs):
|
|
"""Create a specialization of |ASN.1| schema or value object.
|
|
|
|
The subtype relationship between ASN.1 types has no correlation with
|
|
subtype relationship between Python types. ASN.1 type is mainly identified
|
|
by its tag(s) (:py:class:`~pyasn1.type.tag.TagSet`) and value range
|
|
constraints (:py:class:`~pyasn1.type.constraint.ConstraintsIntersection`).
|
|
These ASN.1 type properties are implemented as |ASN.1| attributes.
|
|
|
|
The `subtype()` method accepts the same set arguments as |ASN.1|
|
|
class takes on instantiation except that all parameters
|
|
of the `subtype()` method are optional.
|
|
|
|
With the exception of the arguments described below, the rest of
|
|
supplied arguments they are used to create a copy of `self` taking
|
|
precedence over the ones used to instantiate `self`.
|
|
|
|
The following arguments to `subtype()` create a ASN.1 subtype out of
|
|
|ASN.1| type:
|
|
|
|
Other Parameters
|
|
----------------
|
|
implicitTag: :py:class:`~pyasn1.type.tag.Tag`
|
|
Implicitly apply given ASN.1 tag object to `self`'s
|
|
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
|
|
new object's ASN.1 tag(s).
|
|
|
|
explicitTag: :py:class:`~pyasn1.type.tag.Tag`
|
|
Explicitly apply given ASN.1 tag object to `self`'s
|
|
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
|
|
new object's ASN.1 tag(s).
|
|
|
|
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
|
|
Add ASN.1 constraints object to one of the `self`'s, then
|
|
use the result as new object's ASN.1 constraints.
|
|
|
|
Returns
|
|
-------
|
|
:
|
|
new instance of |ASN.1| schema or value object
|
|
|
|
Note
|
|
----
|
|
Due to the immutable nature of the |ASN.1| object, if no arguments
|
|
are supplied, no new |ASN.1| object will be created and `self` will
|
|
be returned instead.
|
|
"""
|
|
if value is noValue:
|
|
if not kwargs:
|
|
return self
|
|
|
|
value = self._value
|
|
|
|
initializers = self.readOnly.copy()
|
|
|
|
implicitTag = kwargs.pop('implicitTag', None)
|
|
if implicitTag is not None:
|
|
initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
|
|
|
|
explicitTag = kwargs.pop('explicitTag', None)
|
|
if explicitTag is not None:
|
|
initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
|
|
|
|
for arg, option in kwargs.items():
|
|
initializers[arg] += option
|
|
|
|
return self.__class__(value, **initializers)
|
|
|
|
def prettyIn(self, value):
|
|
return value
|
|
|
|
def prettyOut(self, value):
|
|
return str(value)
|
|
|
|
def prettyPrint(self, scope=0):
|
|
return self.prettyOut(self._value)
|
|
|
|
def prettyPrintType(self, scope=0):
|
|
return '%s -> %s' % (self.tagSet, self.__class__.__name__)
|
|
|
|
# Backward compatibility
|
|
AbstractSimpleAsn1Item = SimpleAsn1Type
|
|
|
|
#
|
|
# Constructed types:
|
|
# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice
|
|
# * ASN1 types and values are represened by Python class instances
|
|
# * Value initialization is made for defaulted components only
|
|
# * Primary method of component addressing is by-position. Data model for base
|
|
# type is Python sequence. Additional type-specific addressing methods
|
|
# may be implemented for particular types.
|
|
# * SequenceOf and SetOf types do not implement any additional methods
|
|
# * Sequence, Set and Choice types also implement by-identifier addressing
|
|
# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing
|
|
# * Sequence and Set types may include optional and defaulted
|
|
# components
|
|
# * Constructed types hold a reference to component types used for value
|
|
# verification and ordering.
|
|
# * Component type is a scalar type for SequenceOf/SetOf types and a list
|
|
# of types for Sequence/Set/Choice.
|
|
#
|
|
|
|
|
|
class ConstructedAsn1Type(Asn1Type):
|
|
"""Base class for all constructed classes representing ASN.1 types.
|
|
|
|
ASN.1 distinguishes types by their ability to hold other objects.
|
|
Those "nesting" types are known as *constructed* in ASN.1.
|
|
|
|
In the user code, |ASN.1| class is normally used only for telling
|
|
ASN.1 objects from others.
|
|
|
|
Note
|
|
----
|
|
For as long as ASN.1 is concerned, a way to compare ASN.1 types
|
|
is to use :meth:`isSameTypeWith` and :meth:`isSuperTypeOf` methods.
|
|
"""
|
|
|
|
#: If :obj:`True`, requires exact component type matching,
|
|
#: otherwise subtype relation is only enforced
|
|
strictConstraints = False
|
|
|
|
componentType = None
|
|
|
|
# backward compatibility, unused
|
|
sizeSpec = constraint.ConstraintsIntersection()
|
|
|
|
def __init__(self, **kwargs):
|
|
readOnly = {
|
|
'componentType': self.componentType,
|
|
# backward compatibility, unused
|
|
'sizeSpec': self.sizeSpec
|
|
}
|
|
|
|
# backward compatibility: preserve legacy sizeSpec support
|
|
kwargs = self._moveSizeSpec(**kwargs)
|
|
|
|
readOnly.update(kwargs)
|
|
|
|
Asn1Type.__init__(self, **readOnly)
|
|
|
|
def _moveSizeSpec(self, **kwargs):
|
|
# backward compatibility, unused
|
|
sizeSpec = kwargs.pop('sizeSpec', self.sizeSpec)
|
|
if sizeSpec:
|
|
subtypeSpec = kwargs.pop('subtypeSpec', self.subtypeSpec)
|
|
if subtypeSpec:
|
|
subtypeSpec = sizeSpec
|
|
|
|
else:
|
|
subtypeSpec += sizeSpec
|
|
|
|
kwargs['subtypeSpec'] = subtypeSpec
|
|
|
|
return kwargs
|
|
|
|
def __repr__(self):
|
|
representation = '%s %s object' % (
|
|
self.__class__.__name__, self.isValue and 'value' or 'schema'
|
|
)
|
|
|
|
for attr, value in self.readOnly.items():
|
|
if value is not noValue:
|
|
representation += ', %s=%r' % (attr, value)
|
|
|
|
if self.isValue and self.components:
|
|
representation += ', payload [%s]' % ', '.join(
|
|
[repr(x) for x in self.components])
|
|
|
|
return '<%s>' % representation
|
|
|
|
def __eq__(self, other):
|
|
return self is other or self.components == other
|
|
|
|
def __ne__(self, other):
|
|
return self.components != other
|
|
|
|
def __lt__(self, other):
|
|
return self.components < other
|
|
|
|
def __le__(self, other):
|
|
return self.components <= other
|
|
|
|
def __gt__(self, other):
|
|
return self.components > other
|
|
|
|
def __ge__(self, other):
|
|
return self.components >= other
|
|
|
|
if sys.version_info[0] <= 2:
|
|
def __nonzero__(self):
|
|
return bool(self.components)
|
|
else:
|
|
def __bool__(self):
|
|
return bool(self.components)
|
|
|
|
@property
|
|
def components(self):
|
|
raise error.PyAsn1Error('Method not implemented')
|
|
|
|
def _cloneComponentValues(self, myClone, cloneValueFlag):
|
|
pass
|
|
|
|
def clone(self, **kwargs):
|
|
"""Create a modified version of |ASN.1| schema object.
|
|
|
|
The `clone()` method accepts the same set arguments as |ASN.1|
|
|
class takes on instantiation except that all arguments
|
|
of the `clone()` method are optional.
|
|
|
|
Whatever arguments are supplied, they are used to create a copy
|
|
of `self` taking precedence over the ones used to instantiate `self`.
|
|
|
|
Possible values of `self` are never copied over thus `clone()` can
|
|
only create a new schema object.
|
|
|
|
Returns
|
|
-------
|
|
:
|
|
new instance of |ASN.1| type/value
|
|
|
|
Note
|
|
----
|
|
Due to the mutable nature of the |ASN.1| object, even if no arguments
|
|
are supplied, a new |ASN.1| object will be created and returned.
|
|
"""
|
|
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
|
|
|
|
initializers = self.readOnly.copy()
|
|
initializers.update(kwargs)
|
|
|
|
clone = self.__class__(**initializers)
|
|
|
|
if cloneValueFlag:
|
|
self._cloneComponentValues(clone, cloneValueFlag)
|
|
|
|
return clone
|
|
|
|
def subtype(self, **kwargs):
|
|
"""Create a specialization of |ASN.1| schema object.
|
|
|
|
The `subtype()` method accepts the same set arguments as |ASN.1|
|
|
class takes on instantiation except that all parameters
|
|
of the `subtype()` method are optional.
|
|
|
|
With the exception of the arguments described below, the rest of
|
|
supplied arguments they are used to create a copy of `self` taking
|
|
precedence over the ones used to instantiate `self`.
|
|
|
|
The following arguments to `subtype()` create a ASN.1 subtype out of
|
|
|ASN.1| type.
|
|
|
|
Other Parameters
|
|
----------------
|
|
implicitTag: :py:class:`~pyasn1.type.tag.Tag`
|
|
Implicitly apply given ASN.1 tag object to `self`'s
|
|
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
|
|
new object's ASN.1 tag(s).
|
|
|
|
explicitTag: :py:class:`~pyasn1.type.tag.Tag`
|
|
Explicitly apply given ASN.1 tag object to `self`'s
|
|
:py:class:`~pyasn1.type.tag.TagSet`, then use the result as
|
|
new object's ASN.1 tag(s).
|
|
|
|
subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
|
|
Add ASN.1 constraints object to one of the `self`'s, then
|
|
use the result as new object's ASN.1 constraints.
|
|
|
|
|
|
Returns
|
|
-------
|
|
:
|
|
new instance of |ASN.1| type/value
|
|
|
|
Note
|
|
----
|
|
Due to the mutable nature of the |ASN.1| object, even if no arguments
|
|
are supplied, a new |ASN.1| object will be created and returned.
|
|
"""
|
|
|
|
initializers = self.readOnly.copy()
|
|
|
|
cloneValueFlag = kwargs.pop('cloneValueFlag', False)
|
|
|
|
implicitTag = kwargs.pop('implicitTag', None)
|
|
if implicitTag is not None:
|
|
initializers['tagSet'] = self.tagSet.tagImplicitly(implicitTag)
|
|
|
|
explicitTag = kwargs.pop('explicitTag', None)
|
|
if explicitTag is not None:
|
|
initializers['tagSet'] = self.tagSet.tagExplicitly(explicitTag)
|
|
|
|
for arg, option in kwargs.items():
|
|
initializers[arg] += option
|
|
|
|
clone = self.__class__(**initializers)
|
|
|
|
if cloneValueFlag:
|
|
self._cloneComponentValues(clone, cloneValueFlag)
|
|
|
|
return clone
|
|
|
|
def getComponentByPosition(self, idx):
|
|
raise error.PyAsn1Error('Method not implemented')
|
|
|
|
def setComponentByPosition(self, idx, value, verifyConstraints=True):
|
|
raise error.PyAsn1Error('Method not implemented')
|
|
|
|
def setComponents(self, *args, **kwargs):
|
|
for idx, value in enumerate(args):
|
|
self[idx] = value
|
|
for k in kwargs:
|
|
self[k] = kwargs[k]
|
|
return self
|
|
|
|
# backward compatibility
|
|
|
|
def setDefaultComponents(self):
|
|
pass
|
|
|
|
def getComponentType(self):
|
|
return self.componentType
|
|
|
|
# backward compatibility, unused
|
|
def verifySizeSpec(self):
|
|
self.subtypeSpec(self)
|
|
|
|
|
|
# Backward compatibility
|
|
AbstractConstructedAsn1Item = ConstructedAsn1Type
|