1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061 |
- #
- # This file is part of pyasn1 software.
- #
- # Copyright (c) 2005-2018, Ilya Etingof <etingof@gmail.com>
- # License: http://snmplabs.com/pyasn1/license.html
- #
- import math
- import sys
-
- from pyasn1 import error
- from pyasn1.codec.ber import eoo
- from pyasn1.compat import binary
- from pyasn1.compat import integer
- from pyasn1.compat import octets
- from pyasn1.type import base
- from pyasn1.type import constraint
- from pyasn1.type import namedtype
- from pyasn1.type import namedval
- from pyasn1.type import tag
- from pyasn1.type import tagmap
-
- NoValue = base.NoValue
- noValue = NoValue()
-
- __all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null',
- 'ObjectIdentifier', 'Real', 'Enumerated',
- 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf',
- 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any',
- 'NoValue', 'noValue']
-
- # "Simple" ASN.1 types (yet incomplete)
-
-
- class Integer(base.AbstractSimpleAsn1Item):
- """Create |ASN.1| type or object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
-
- Keyword Args
- ------------
- value: :class:`int`, :class:`str` or |ASN.1| object
- Python integer or string literal or |ASN.1| class instance.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
- Object representing non-default symbolic aliases for numbers
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
-
- .. code-block:: python
-
- class ErrorCode(Integer):
- '''
- ASN.1 specification:
-
- ErrorCode ::=
- INTEGER { disk-full(1), no-disk(-1),
- disk-not-formatted(2) }
-
- error ErrorCode ::= disk-full
- '''
- namedValues = NamedValues(
- ('disk-full', 1), ('no-disk', -1),
- ('disk-not-formatted', 2)
- )
-
- error = ErrorCode('disk-full')
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
- #: representing symbolic aliases for numbers
- namedValues = namedval.NamedValues()
-
- # Optimization for faster codec lookup
- typeId = base.AbstractSimpleAsn1Item.getTypeId()
-
- def __init__(self, value=noValue, **kwargs):
- if 'namedValues' not in kwargs:
- kwargs['namedValues'] = self.namedValues
-
- base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
-
- def __and__(self, value):
- return self.clone(self._value & value)
-
- def __rand__(self, value):
- return self.clone(value & self._value)
-
- def __or__(self, value):
- return self.clone(self._value | value)
-
- def __ror__(self, value):
- return self.clone(value | self._value)
-
- def __xor__(self, value):
- return self.clone(self._value ^ value)
-
- def __rxor__(self, value):
- return self.clone(value ^ self._value)
-
- def __lshift__(self, value):
- return self.clone(self._value << value)
-
- def __rshift__(self, value):
- return self.clone(self._value >> value)
-
- def __add__(self, value):
- return self.clone(self._value + value)
-
- def __radd__(self, value):
- return self.clone(value + self._value)
-
- def __sub__(self, value):
- return self.clone(self._value - value)
-
- def __rsub__(self, value):
- return self.clone(value - self._value)
-
- def __mul__(self, value):
- return self.clone(self._value * value)
-
- def __rmul__(self, value):
- return self.clone(value * self._value)
-
- def __mod__(self, value):
- return self.clone(self._value % value)
-
- def __rmod__(self, value):
- return self.clone(value % self._value)
-
- def __pow__(self, value, modulo=None):
- return self.clone(pow(self._value, value, modulo))
-
- def __rpow__(self, value):
- return self.clone(pow(value, self._value))
-
- def __floordiv__(self, value):
- return self.clone(self._value // value)
-
- def __rfloordiv__(self, value):
- return self.clone(value // self._value)
-
- if sys.version_info[0] <= 2:
- def __div__(self, value):
- if isinstance(value, float):
- return Real(self._value / value)
- else:
- return self.clone(self._value / value)
-
- def __rdiv__(self, value):
- if isinstance(value, float):
- return Real(value / self._value)
- else:
- return self.clone(value / self._value)
- else:
- def __truediv__(self, value):
- return Real(self._value / value)
-
- def __rtruediv__(self, value):
- return Real(value / self._value)
-
- def __divmod__(self, value):
- return self.clone(divmod(self._value, value))
-
- def __rdivmod__(self, value):
- return self.clone(divmod(value, self._value))
-
- __hash__ = base.AbstractSimpleAsn1Item.__hash__
-
- def __int__(self):
- return int(self._value)
-
- if sys.version_info[0] <= 2:
- def __long__(self):
- return long(self._value)
-
- def __float__(self):
- return float(self._value)
-
- def __abs__(self):
- return self.clone(abs(self._value))
-
- def __index__(self):
- return int(self._value)
-
- def __pos__(self):
- return self.clone(+self._value)
-
- def __neg__(self):
- return self.clone(-self._value)
-
- def __invert__(self):
- return self.clone(~self._value)
-
- def __round__(self, n=0):
- r = round(self._value, n)
- if n:
- return self.clone(r)
- else:
- return r
-
- def __floor__(self):
- return math.floor(self._value)
-
- def __ceil__(self):
- return math.ceil(self._value)
-
- if sys.version_info[0:2] > (2, 5):
- def __trunc__(self):
- return self.clone(math.trunc(self._value))
-
- def __lt__(self, value):
- return self._value < value
-
- def __le__(self, value):
- return self._value <= value
-
- def __eq__(self, value):
- return self._value == value
-
- def __ne__(self, value):
- return self._value != value
-
- def __gt__(self, value):
- return self._value > value
-
- def __ge__(self, value):
- return self._value >= value
-
- def prettyIn(self, value):
- try:
- return int(value)
-
- except ValueError:
- try:
- return self.namedValues[value]
-
- except KeyError:
- raise error.PyAsn1Error(
- 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1])
- )
-
- def prettyOut(self, value):
- try:
- return str(self.namedValues[value])
-
- except KeyError:
- return str(value)
-
- # backward compatibility
-
- def getNamedValues(self):
- return self.namedValues
-
-
- class Boolean(Integer):
- """Create |ASN.1| type or object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
-
- Keyword Args
- ------------
- value: :class:`int`, :class:`str` or |ASN.1| object
- Python integer or boolean or string literal or |ASN.1| class instance.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
- Object representing non-default symbolic aliases for numbers
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class RoundResult(Boolean):
- '''
- ASN.1 specification:
-
- RoundResult ::= BOOLEAN
-
- ok RoundResult ::= TRUE
- ko RoundResult ::= FALSE
- '''
- ok = RoundResult(True)
- ko = RoundResult(False)
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01),
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1)
-
- #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
- #: representing symbolic aliases for numbers
- namedValues = namedval.NamedValues(('False', 0), ('True', 1))
-
- # Optimization for faster codec lookup
- typeId = Integer.getTypeId()
-
- if sys.version_info[0] < 3:
- SizedIntegerBase = long
- else:
- SizedIntegerBase = int
-
-
- class SizedInteger(SizedIntegerBase):
- bitLength = leadingZeroBits = None
-
- def setBitLength(self, bitLength):
- self.bitLength = bitLength
- self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0)
- return self
-
- def __len__(self):
- if self.bitLength is None:
- self.setBitLength(integer.bitLength(self))
-
- return self.bitLength
-
-
- class BitString(base.AbstractSimpleAsn1Item):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type both Python :class:`tuple` (as a tuple
- of bits) and :class:`int` objects.
-
- Keyword Args
- ------------
- value: :class:`int`, :class:`str` or |ASN.1| object
- Python integer or string literal representing binary or hexadecimal
- number or sequence of integer bits or |ASN.1| object.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
- Object representing non-default symbolic aliases for numbers
-
- binValue: :py:class:`str`
- Binary string initializer to use instead of the *value*.
- Example: '10110011'.
-
- hexValue: :py:class:`str`
- Hexadecimal string initializer to use instead of the *value*.
- Example: 'DEADBEEF'.
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class Rights(BitString):
- '''
- ASN.1 specification:
-
- Rights ::= BIT STRING { user-read(0), user-write(1),
- group-read(2), group-write(3),
- other-read(4), other-write(5) }
-
- group1 Rights ::= { group-read, group-write }
- group2 Rights ::= '0011'B
- group3 Rights ::= '3'H
- '''
- namedValues = NamedValues(
- ('user-read', 0), ('user-write', 1),
- ('group-read', 2), ('group-write', 3),
- ('other-read', 4), ('other-write', 5)
- )
-
- group1 = Rights(('group-read', 'group-write'))
- group2 = Rights('0011')
- group3 = Rights(0x3)
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
- #: representing symbolic aliases for numbers
- namedValues = namedval.NamedValues()
-
- # Optimization for faster codec lookup
- typeId = base.AbstractSimpleAsn1Item.getTypeId()
-
- defaultBinValue = defaultHexValue = noValue
-
- def __init__(self, value=noValue, **kwargs):
- if value is noValue:
- if kwargs:
- try:
- value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True)
-
- except KeyError:
- pass
-
- try:
- value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True)
-
- except KeyError:
- pass
-
- if value is noValue:
- if self.defaultBinValue is not noValue:
- value = self.fromBinaryString(self.defaultBinValue, internalFormat=True)
-
- elif self.defaultHexValue is not noValue:
- value = self.fromHexString(self.defaultHexValue, internalFormat=True)
-
- if 'namedValues' not in kwargs:
- kwargs['namedValues'] = self.namedValues
-
- base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
-
- def __str__(self):
- return self.asBinary()
-
- def __eq__(self, other):
- other = self.prettyIn(other)
- return self is other or self._value == other and len(self._value) == len(other)
-
- def __ne__(self, other):
- other = self.prettyIn(other)
- return self._value != other or len(self._value) != len(other)
-
- def __lt__(self, other):
- other = self.prettyIn(other)
- return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other
-
- def __le__(self, other):
- other = self.prettyIn(other)
- return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other
-
- def __gt__(self, other):
- other = self.prettyIn(other)
- return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other
-
- def __ge__(self, other):
- other = self.prettyIn(other)
- return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other
-
- # Immutable sequence object protocol
-
- def __len__(self):
- return len(self._value)
-
- def __getitem__(self, i):
- if i.__class__ is slice:
- return self.clone([self[x] for x in range(*i.indices(len(self)))])
- else:
- length = len(self._value) - 1
- if i > length or i < 0:
- raise IndexError('bit index out of range')
- return (self._value >> (length - i)) & 1
-
- def __iter__(self):
- length = len(self._value)
- while length:
- length -= 1
- yield (self._value >> length) & 1
-
- def __reversed__(self):
- return reversed(tuple(self))
-
- # arithmetic operators
-
- def __add__(self, value):
- value = self.prettyIn(value)
- return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value)))
-
- def __radd__(self, value):
- value = self.prettyIn(value)
- return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value)))
-
- def __mul__(self, value):
- bitString = self._value
- while value > 1:
- bitString <<= len(self._value)
- bitString |= self._value
- value -= 1
- return self.clone(bitString)
-
- def __rmul__(self, value):
- return self * value
-
- def __lshift__(self, count):
- return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count))
-
- def __rshift__(self, count):
- return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count)))
-
- def __int__(self):
- return self._value
-
- def __float__(self):
- return float(self._value)
-
- if sys.version_info[0] < 3:
- def __long__(self):
- return self._value
-
- def asNumbers(self):
- """Get |ASN.1| value as a sequence of 8-bit integers.
-
- If |ASN.1| object length is not a multiple of 8, result
- will be left-padded with zeros.
- """
- return tuple(octets.octs2ints(self.asOctets()))
-
- def asOctets(self):
- """Get |ASN.1| value as a sequence of octets.
-
- If |ASN.1| object length is not a multiple of 8, result
- will be left-padded with zeros.
- """
- return integer.to_bytes(self._value, length=len(self))
-
- def asInteger(self):
- """Get |ASN.1| value as a single integer value.
- """
- return self._value
-
- def asBinary(self):
- """Get |ASN.1| value as a text string of bits.
- """
- binString = binary.bin(self._value)[2:]
- return '0' * (len(self._value) - len(binString)) + binString
-
- @classmethod
- def fromHexString(cls, value, internalFormat=False, prepend=None):
- """Create a |ASN.1| object initialized from the hex string.
-
- Parameters
- ----------
- value: :class:`str`
- Text string like 'DEADBEEF'
- """
- try:
- value = SizedInteger(value, 16).setBitLength(len(value) * 4)
-
- except ValueError:
- raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1]))
-
- if prepend is not None:
- value = SizedInteger(
- (SizedInteger(prepend) << len(value)) | value
- ).setBitLength(len(prepend) + len(value))
-
- if not internalFormat:
- value = cls(value)
-
- return value
-
- @classmethod
- def fromBinaryString(cls, value, internalFormat=False, prepend=None):
- """Create a |ASN.1| object initialized from a string of '0' and '1'.
-
- Parameters
- ----------
- value: :class:`str`
- Text string like '1010111'
- """
- try:
- value = SizedInteger(value or '0', 2).setBitLength(len(value))
-
- except ValueError:
- raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1]))
-
- if prepend is not None:
- value = SizedInteger(
- (SizedInteger(prepend) << len(value)) | value
- ).setBitLength(len(prepend) + len(value))
-
- if not internalFormat:
- value = cls(value)
-
- return value
-
- @classmethod
- def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0):
- """Create a |ASN.1| object initialized from a string.
-
- Parameters
- ----------
- value: :class:`str` (Py2) or :class:`bytes` (Py3)
- Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3)
- """
- value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding)
-
- if prepend is not None:
- value = SizedInteger(
- (SizedInteger(prepend) << len(value)) | value
- ).setBitLength(len(prepend) + len(value))
-
- if not internalFormat:
- value = cls(value)
-
- return value
-
- def prettyIn(self, value):
- if isinstance(value, SizedInteger):
- return value
- elif octets.isStringType(value):
- if not value:
- return SizedInteger(0).setBitLength(0)
-
- elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated)
- if value[-2:] == '\'B':
- return self.fromBinaryString(value[1:-2], internalFormat=True)
- elif value[-2:] == '\'H':
- return self.fromHexString(value[1:-2], internalFormat=True)
- else:
- raise error.PyAsn1Error(
- 'Bad BIT STRING value notation %s' % (value,)
- )
-
- elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active'
- names = [x.strip() for x in value.split(',')]
-
- try:
-
- bitPositions = [self.namedValues[name] for name in names]
-
- except KeyError:
- raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,))
-
- rightmostPosition = max(bitPositions)
-
- number = 0
- for bitPosition in bitPositions:
- number |= 1 << (rightmostPosition - bitPosition)
-
- return SizedInteger(number).setBitLength(rightmostPosition + 1)
-
- elif value.startswith('0x'):
- return self.fromHexString(value[2:], internalFormat=True)
-
- elif value.startswith('0b'):
- return self.fromBinaryString(value[2:], internalFormat=True)
-
- else: # assume plain binary string like '1011'
- return self.fromBinaryString(value, internalFormat=True)
-
- elif isinstance(value, (tuple, list)):
- return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True)
-
- elif isinstance(value, BitString):
- return SizedInteger(value).setBitLength(len(value))
-
- elif isinstance(value, intTypes):
- return SizedInteger(value)
-
- else:
- raise error.PyAsn1Error(
- 'Bad BitString initializer type \'%s\'' % (value,)
- )
-
-
- try:
- # noinspection PyStatementEffect
- all
-
- except NameError: # Python 2.4
- # noinspection PyShadowingBuiltins
- def all(iterable):
- for element in iterable:
- if not element:
- return False
- return True
-
-
- class OctetString(base.AbstractSimpleAsn1Item):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3 :class:`bytes`.
- When used in Unicode context, |ASN.1| type assumes "|encoding|" serialisation.
-
- Keyword Args
- ------------
- value: :class:`str`, :class:`bytes` or |ASN.1| object
- string (Python 2) or bytes (Python 3), alternatively unicode object
- (Python 2) or string (Python 3) representing character string to be
- serialised into octets (note `encoding` parameter) or |ASN.1| object.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- encoding: :py:class:`str`
- Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
- :class:`str` (Python 3) the payload when |ASN.1| object is used
- in text string context.
-
- binValue: :py:class:`str`
- Binary string initializer to use instead of the *value*.
- Example: '10110011'.
-
- hexValue: :py:class:`str`
- Hexadecimal string initializer to use instead of the *value*.
- Example: 'DEADBEEF'.
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class Icon(OctetString):
- '''
- ASN.1 specification:
-
- Icon ::= OCTET STRING
-
- icon1 Icon ::= '001100010011001000110011'B
- icon2 Icon ::= '313233'H
- '''
- icon1 = Icon.fromBinaryString('001100010011001000110011')
- icon2 = Icon.fromHexString('313233')
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- # Optimization for faster codec lookup
- typeId = base.AbstractSimpleAsn1Item.getTypeId()
-
- defaultBinValue = defaultHexValue = noValue
- encoding = 'iso-8859-1'
-
- def __init__(self, value=noValue, **kwargs):
- if kwargs:
- if value is noValue:
- try:
- value = self.fromBinaryString(kwargs.pop('binValue'))
-
- except KeyError:
- pass
-
- try:
- value = self.fromHexString(kwargs.pop('hexValue'))
-
- except KeyError:
- pass
-
- if value is noValue:
- if self.defaultBinValue is not noValue:
- value = self.fromBinaryString(self.defaultBinValue)
-
- elif self.defaultHexValue is not noValue:
- value = self.fromHexString(self.defaultHexValue)
-
- if 'encoding' not in kwargs:
- kwargs['encoding'] = self.encoding
-
- base.AbstractSimpleAsn1Item.__init__(self, value, **kwargs)
-
- if sys.version_info[0] <= 2:
- def prettyIn(self, value):
- if isinstance(value, str):
- return value
- elif isinstance(value, unicode):
- try:
- return value.encode(self.encoding)
- except (LookupError, UnicodeEncodeError):
- raise error.PyAsn1Error(
- "Can't encode string '%s' with codec %s" % (value, self.encoding)
- )
- elif isinstance(value, (tuple, list)):
- try:
- return ''.join([chr(x) for x in value])
- except ValueError:
- raise error.PyAsn1Error(
- "Bad %s initializer '%s'" % (self.__class__.__name__, value)
- )
- else:
- return str(value)
-
- def __str__(self):
- return str(self._value)
-
- def __unicode__(self):
- try:
- return self._value.decode(self.encoding)
-
- except UnicodeDecodeError:
- raise error.PyAsn1Error(
- "Can't decode string '%s' with codec %s" % (self._value, self.encoding)
- )
-
- def asOctets(self):
- return str(self._value)
-
- def asNumbers(self):
- return tuple([ord(x) for x in self._value])
-
- else:
- def prettyIn(self, value):
- if isinstance(value, bytes):
- return value
- elif isinstance(value, str):
- try:
- return value.encode(self.encoding)
- except UnicodeEncodeError:
- raise error.PyAsn1Error(
- "Can't encode string '%s' with '%s' codec" % (value, self.encoding)
- )
- elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way
- return value.asOctets()
- elif isinstance(value, base.AbstractSimpleAsn1Item): # this mostly targets Integer objects
- return self.prettyIn(str(value))
- elif isinstance(value, (tuple, list)):
- return self.prettyIn(bytes(value))
- else:
- return bytes(value)
-
- def __str__(self):
- try:
- return self._value.decode(self.encoding)
-
- except UnicodeDecodeError:
- raise error.PyAsn1Error(
- "Can't decode string '%s' with '%s' codec at '%s'" % (self._value, self.encoding, self.__class__.__name__)
- )
-
- def __bytes__(self):
- return bytes(self._value)
-
- def asOctets(self):
- return bytes(self._value)
-
- def asNumbers(self):
- return tuple(self._value)
-
- #
- # Normally, `.prettyPrint()` is called from `__str__()`. Historically,
- # OctetString.prettyPrint() used to return hexified payload
- # representation in cases when non-printable content is present. At the
- # same time `str()` used to produce either octet-stream (Py2) or
- # text (Py3) representations.
- #
- # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is
- # reversed to preserve the original behaviour.
- #
- # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness
- # and end up with just `__str__()` producing hexified representation while
- # both text and octet-stream representation should only be requested via
- # the `.asOctets()` method.
- #
- # Note: ASN.1 OCTET STRING is never mean to contain text!
- #
-
- def prettyOut(self, value):
- return value
-
- def prettyPrint(self, scope=0):
- # first see if subclass has its own .prettyOut()
- value = self.prettyOut(self._value)
-
- if value is not self._value:
- return value
-
- numbers = self.asNumbers()
-
- for x in numbers:
- # hexify if needed
- if x < 32 or x > 126:
- return '0x' + ''.join(('%.2x' % x for x in numbers))
- else:
- # this prevents infinite recursion
- return OctetString.__str__(self)
-
- @staticmethod
- def fromBinaryString(value):
- """Create a |ASN.1| object initialized from a string of '0' and '1'.
-
- Parameters
- ----------
- value: :class:`str`
- Text string like '1010111'
- """
- bitNo = 8
- byte = 0
- r = []
- for v in value:
- if bitNo:
- bitNo -= 1
- else:
- bitNo = 7
- r.append(byte)
- byte = 0
- if v in ('0', '1'):
- v = int(v)
- else:
- raise error.PyAsn1Error(
- 'Non-binary OCTET STRING initializer %s' % (v,)
- )
- byte |= v << bitNo
-
- r.append(byte)
-
- return octets.ints2octs(r)
-
- @staticmethod
- def fromHexString(value):
- """Create a |ASN.1| object initialized from the hex string.
-
- Parameters
- ----------
- value: :class:`str`
- Text string like 'DEADBEEF'
- """
- r = []
- p = []
- for v in value:
- if p:
- r.append(int(p + v, 16))
- p = None
- else:
- p = v
- if p:
- r.append(int(p + '0', 16))
-
- return octets.ints2octs(r)
-
- # Immutable sequence object protocol
-
- def __len__(self):
- return len(self._value)
-
- def __getitem__(self, i):
- if i.__class__ is slice:
- return self.clone(self._value[i])
- else:
- return self._value[i]
-
- def __iter__(self):
- return iter(self._value)
-
- def __contains__(self, value):
- return value in self._value
-
- def __add__(self, value):
- return self.clone(self._value + self.prettyIn(value))
-
- def __radd__(self, value):
- return self.clone(self.prettyIn(value) + self._value)
-
- def __mul__(self, value):
- return self.clone(self._value * value)
-
- def __rmul__(self, value):
- return self * value
-
- def __int__(self):
- return int(self._value)
-
- def __float__(self):
- return float(self._value)
-
- def __reversed__(self):
- return reversed(self._value)
-
-
- class Null(OctetString):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`str` objects (always empty).
-
- Keyword Args
- ------------
- value: :class:`str` or :py:class:`~pyasn1.type.univ.Null` object
- Python empty string literal or any object that evaluates to `False`
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class Ack(Null):
- '''
- ASN.1 specification:
-
- Ack ::= NULL
- '''
- ack = Ack('')
- """
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05)
- )
- subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs(''))
-
- # Optimization for faster codec lookup
- typeId = OctetString.getTypeId()
-
- def prettyIn(self, value):
- if value:
- return value
-
- return octets.str2octs('')
-
- if sys.version_info[0] <= 2:
- intTypes = (int, long)
- else:
- intTypes = (int,)
-
- numericTypes = intTypes + (float,)
-
-
- class ObjectIdentifier(base.AbstractSimpleAsn1Item):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`tuple` objects (tuple of non-negative integers).
-
- Keyword Args
- ------------
- value: :class:`tuple`, :class:`str` or |ASN.1| object
- Python sequence of :class:`int` or string literal or |ASN.1| object.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class ID(ObjectIdentifier):
- '''
- ASN.1 specification:
-
- ID ::= OBJECT IDENTIFIER
-
- id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) }
- id-bp ID ::= { id-edims 11 }
- '''
- id_edims = ID('2.6.7')
- id_bp = id_edims + (11,)
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- # Optimization for faster codec lookup
- typeId = base.AbstractSimpleAsn1Item.getTypeId()
-
- def __add__(self, other):
- return self.clone(self._value + other)
-
- def __radd__(self, other):
- return self.clone(other + self._value)
-
- def asTuple(self):
- return self._value
-
- # Sequence object protocol
-
- def __len__(self):
- return len(self._value)
-
- def __getitem__(self, i):
- if i.__class__ is slice:
- return self.clone(self._value[i])
- else:
- return self._value[i]
-
- def __iter__(self):
- return iter(self._value)
-
- def __contains__(self, value):
- return value in self._value
-
- def index(self, suboid):
- return self._value.index(suboid)
-
- def isPrefixOf(self, other):
- """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object.
-
- Parameters
- ----------
- other: |ASN.1| object
- |ASN.1| object
-
- Returns
- -------
- : :class:`bool`
- :class:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object
- or :class:`False` otherwise.
- """
- l = len(self)
- if l <= len(other):
- if self._value[:l] == other[:l]:
- return True
- return False
-
- def prettyIn(self, value):
- if isinstance(value, ObjectIdentifier):
- return tuple(value)
- elif octets.isStringType(value):
- if '-' in value:
- raise error.PyAsn1Error(
- 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
- )
- try:
- return tuple([int(subOid) for subOid in value.split('.') if subOid])
- except ValueError:
- raise error.PyAsn1Error(
- 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
- )
-
- try:
- tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0])
-
- except (ValueError, TypeError):
- raise error.PyAsn1Error(
- 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1])
- )
-
- if len(tupleOfInts) == len(value):
- return tupleOfInts
-
- raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__))
-
- def prettyOut(self, value):
- return '.'.join([str(x) for x in value])
-
-
- class Real(base.AbstractSimpleAsn1Item):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`float` objects.
- Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its
- elements are mantissa, base and exponent.
-
- Keyword Args
- ------------
- value: :class:`tuple`, :class:`float` or |ASN.1| object
- Python sequence of :class:`int` (representing mantissa, base and
- exponent) or float instance or *Real* class instance.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class Pi(Real):
- '''
- ASN.1 specification:
-
- Pi ::= REAL
-
- pi Pi ::= { mantissa 314159, base 10, exponent -5 }
-
- '''
- pi = Pi((314159, 10, -5))
- """
- binEncBase = None # binEncBase = 16 is recommended for large numbers
-
- try:
- _plusInf = float('inf')
- _minusInf = float('-inf')
- _inf = _plusInf, _minusInf
-
- except ValueError:
- # Infinity support is platform and Python dependent
- _plusInf = _minusInf = None
- _inf = ()
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- # Optimization for faster codec lookup
- typeId = base.AbstractSimpleAsn1Item.getTypeId()
-
- @staticmethod
- def __normalizeBase10(value):
- m, b, e = value
- while m and m % 10 == 0:
- m /= 10
- e += 1
- return m, b, e
-
- def prettyIn(self, value):
- if isinstance(value, tuple) and len(value) == 3:
- if (not isinstance(value[0], numericTypes) or
- not isinstance(value[1], intTypes) or
- not isinstance(value[2], intTypes)):
- raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,))
- if (isinstance(value[0], float) and
- self._inf and value[0] in self._inf):
- return value[0]
- if value[1] not in (2, 10):
- raise error.PyAsn1Error(
- 'Prohibited base for Real value: %s' % (value[1],)
- )
- if value[1] == 10:
- value = self.__normalizeBase10(value)
- return value
- elif isinstance(value, intTypes):
- return self.__normalizeBase10((value, 10, 0))
- elif isinstance(value, float) or octets.isStringType(value):
- if octets.isStringType(value):
- try:
- value = float(value)
- except ValueError:
- raise error.PyAsn1Error(
- 'Bad real value syntax: %s' % (value,)
- )
- if self._inf and value in self._inf:
- return value
- else:
- e = 0
- while int(value) != value:
- value *= 10
- e -= 1
- return self.__normalizeBase10((int(value), 10, e))
- elif isinstance(value, Real):
- return tuple(value)
- raise error.PyAsn1Error(
- 'Bad real value syntax: %s' % (value,)
- )
-
- def prettyPrint(self, scope=0):
- try:
- return self.prettyOut(float(self))
-
- except OverflowError:
- return '<overflow>'
-
- @property
- def isPlusInf(self):
- """Indicate PLUS-INFINITY object value
-
- Returns
- -------
- : :class:`bool`
- :class:`True` if calling object represents plus infinity
- or :class:`False` otherwise.
-
- """
- return self._value == self._plusInf
-
- @property
- def isMinusInf(self):
- """Indicate MINUS-INFINITY object value
-
- Returns
- -------
- : :class:`bool`
- :class:`True` if calling object represents minus infinity
- or :class:`False` otherwise.
- """
- return self._value == self._minusInf
-
- @property
- def isInf(self):
- return self._value in self._inf
-
- def __add__(self, value):
- return self.clone(float(self) + value)
-
- def __radd__(self, value):
- return self + value
-
- def __mul__(self, value):
- return self.clone(float(self) * value)
-
- def __rmul__(self, value):
- return self * value
-
- def __sub__(self, value):
- return self.clone(float(self) - value)
-
- def __rsub__(self, value):
- return self.clone(value - float(self))
-
- def __mod__(self, value):
- return self.clone(float(self) % value)
-
- def __rmod__(self, value):
- return self.clone(value % float(self))
-
- def __pow__(self, value, modulo=None):
- return self.clone(pow(float(self), value, modulo))
-
- def __rpow__(self, value):
- return self.clone(pow(value, float(self)))
-
- if sys.version_info[0] <= 2:
- def __div__(self, value):
- return self.clone(float(self) / value)
-
- def __rdiv__(self, value):
- return self.clone(value / float(self))
- else:
- def __truediv__(self, value):
- return self.clone(float(self) / value)
-
- def __rtruediv__(self, value):
- return self.clone(value / float(self))
-
- def __divmod__(self, value):
- return self.clone(float(self) // value)
-
- def __rdivmod__(self, value):
- return self.clone(value // float(self))
-
- def __int__(self):
- return int(float(self))
-
- if sys.version_info[0] <= 2:
- def __long__(self):
- return long(float(self))
-
- def __float__(self):
- if self._value in self._inf:
- return self._value
- else:
- return float(
- self._value[0] * pow(self._value[1], self._value[2])
- )
-
- def __abs__(self):
- return self.clone(abs(float(self)))
-
- def __pos__(self):
- return self.clone(+float(self))
-
- def __neg__(self):
- return self.clone(-float(self))
-
- def __round__(self, n=0):
- r = round(float(self), n)
- if n:
- return self.clone(r)
- else:
- return r
-
- def __floor__(self):
- return self.clone(math.floor(float(self)))
-
- def __ceil__(self):
- return self.clone(math.ceil(float(self)))
-
- if sys.version_info[0:2] > (2, 5):
- def __trunc__(self):
- return self.clone(math.trunc(float(self)))
-
- def __lt__(self, value):
- return float(self) < value
-
- def __le__(self, value):
- return float(self) <= value
-
- def __eq__(self, value):
- return float(self) == value
-
- def __ne__(self, value):
- return float(self) != value
-
- def __gt__(self, value):
- return float(self) > value
-
- def __ge__(self, value):
- return float(self) >= value
-
- if sys.version_info[0] <= 2:
- def __nonzero__(self):
- return bool(float(self))
- else:
- def __bool__(self):
- return bool(float(self))
-
- __hash__ = base.AbstractSimpleAsn1Item.__hash__
-
- def __getitem__(self, idx):
- if self._value in self._inf:
- raise error.PyAsn1Error('Invalid infinite value operation')
- else:
- return self._value[idx]
-
- # compatibility stubs
-
- def isPlusInfinity(self):
- return self.isPlusInf
-
- def isMinusInfinity(self):
- return self.isMinusInf
-
- def isInfinity(self):
- return self.isInf
-
-
- class Enumerated(Integer):
- """Create |ASN.1| type or object.
-
- |ASN.1| objects are immutable and duck-type Python :class:`int` objects.
-
- Keyword Args
- ------------
- value: :class:`int`, :class:`str` or |ASN.1| object
- Python integer or string literal or |ASN.1| class instance.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- namedValues: :py:class:`~pyasn1.type.namedval.NamedValues`
- Object representing non-default symbolic aliases for numbers
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
-
- .. code-block:: python
-
- class RadioButton(Enumerated):
- '''
- ASN.1 specification:
-
- RadioButton ::= ENUMERATED { button1(0), button2(1),
- button3(2) }
-
- selected-by-default RadioButton ::= button1
- '''
- namedValues = NamedValues(
- ('button1', 0), ('button2', 1),
- ('button3', 2)
- )
-
- selected_by_default = RadioButton('button1')
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- # Optimization for faster codec lookup
- typeId = Integer.getTypeId()
-
- #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object
- #: representing symbolic aliases for numbers
- namedValues = namedval.NamedValues()
-
-
- # "Structured" ASN.1 types
-
- class SequenceOfAndSetOfBase(base.AbstractConstructedAsn1Item):
- """Create |ASN.1| type.
-
- |ASN.1| objects are mutable and duck-type Python :class:`list` objects.
-
- Keyword Args
- ------------
- componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A pyasn1 object representing ASN.1 type allowed within |ASN.1| type
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
-
- Examples
- --------
-
- .. code-block:: python
-
- class LotteryDraw(SequenceOf): # SetOf is similar
- '''
- ASN.1 specification:
-
- LotteryDraw ::= SEQUENCE OF INTEGER
- '''
- componentType = Integer()
-
- lotteryDraw = LotteryDraw()
- lotteryDraw.extend([123, 456, 789])
- """
- def __init__(self, *args, **kwargs):
- # support positional params for backward compatibility
- if args:
- for key, value in zip(('componentType', 'tagSet',
- 'subtypeSpec', 'sizeSpec'), args):
- if key in kwargs:
- raise error.PyAsn1Error('Conflicting positional and keyword params!')
- kwargs['componentType'] = value
-
- base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
-
- # Python list protocol
-
- def __getitem__(self, idx):
- try:
- return self.getComponentByPosition(idx)
-
- except error.PyAsn1Error:
- raise IndexError(sys.exc_info()[1])
-
- def __setitem__(self, idx, value):
- try:
- self.setComponentByPosition(idx, value)
-
- except error.PyAsn1Error:
- raise IndexError(sys.exc_info()[1])
-
- def clear(self):
- self._componentValues = []
-
- def append(self, value):
- self[len(self)] = value
-
- def count(self, value):
- return self._componentValues.count(value)
-
- def extend(self, values):
- for value in values:
- self.append(value)
-
- def index(self, value, start=0, stop=None):
- if stop is None:
- stop = len(self)
- try:
- return self._componentValues.index(value, start, stop)
-
- except error.PyAsn1Error:
- raise ValueError(sys.exc_info()[1])
-
- def reverse(self):
- self._componentValues.reverse()
-
- def sort(self, key=None, reverse=False):
- self._componentValues.sort(key=key, reverse=reverse)
-
- def __iter__(self):
- return iter(self._componentValues)
-
- def _cloneComponentValues(self, myClone, cloneValueFlag):
- for idx, componentValue in enumerate(self._componentValues):
- if componentValue is not noValue:
- if isinstance(componentValue, base.AbstractConstructedAsn1Item):
- myClone.setComponentByPosition(
- idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
- )
- else:
- myClone.setComponentByPosition(idx, componentValue.clone())
-
- def getComponentByPosition(self, idx, default=noValue, instantiate=True):
- """Return |ASN.1| type component value by position.
-
- Equivalent to Python sequence subscription operation (e.g. `[]`).
-
- Parameters
- ----------
- idx : :class:`int`
- Component index (zero-based). Must either refer to an existing
- component or to N+1 component (if *componentType* is set). In the latter
- case a new component type gets instantiated and appended to the |ASN.1|
- sequence.
-
- Keyword Args
- ------------
- default: :class:`object`
- If set and requested component is a schema object, return the `default`
- object instead of the requested component.
-
- instantiate: :class:`bool`
- If `True` (default), inner component will be automatically instantiated.
- If 'False' either existing component or the `noValue` object will be
- returned.
-
- Returns
- -------
- : :py:class:`~pyasn1.type.base.PyAsn1Item`
- Instantiate |ASN.1| component type or return existing component value
-
- Examples
- --------
-
- .. code-block:: python
-
- # can also be SetOf
- class MySequenceOf(SequenceOf):
- componentType = OctetString()
-
- s = MySequenceOf()
-
- # returns component #0 with `.isValue` property False
- s.getComponentByPosition(0)
-
- # returns None
- s.getComponentByPosition(0, default=None)
-
- s.clear()
-
- # returns noValue
- s.getComponentByPosition(0, instantiate=False)
-
- # sets component #0 to OctetString() ASN.1 schema
- # object and returns it
- s.getComponentByPosition(0, instantiate=True)
-
- # sets component #0 to ASN.1 value object
- s.setComponentByPosition(0, 'ABCD')
-
- # returns OctetString('ABCD') value object
- s.getComponentByPosition(0, instantiate=False)
-
- s.clear()
-
- # returns noValue
- s.getComponentByPosition(0, instantiate=False)
- """
- try:
- componentValue = self._componentValues[idx]
-
- except IndexError:
- if not instantiate:
- return default
-
- self.setComponentByPosition(idx)
-
- componentValue = self._componentValues[idx]
-
- if default is noValue or componentValue.isValue:
- return componentValue
- else:
- return default
-
- def setComponentByPosition(self, idx, value=noValue,
- verifyConstraints=True,
- matchTags=True,
- matchConstraints=True):
- """Assign |ASN.1| type component by position.
-
- Equivalent to Python sequence item assignment operation (e.g. `[]`)
- or list.append() (when idx == len(self)).
-
- Parameters
- ----------
- idx: :class:`int`
- Component index (zero-based). Must either refer to existing
- component or to N+1 component. In the latter case a new component
- type gets instantiated (if *componentType* is set, or given ASN.1
- object is taken otherwise) and appended to the |ASN.1| sequence.
-
- Keyword Args
- ------------
- value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A Python value to initialize |ASN.1| component with (if *componentType* is set)
- or ASN.1 value object to assign to |ASN.1| component.
-
- verifyConstraints: :class:`bool`
- If `False`, skip constraints validation
-
- matchTags: :class:`bool`
- If `False`, skip component tags matching
-
- matchConstraints: :class:`bool`
- If `False`, skip component constraints matching
-
- Returns
- -------
- self
-
- Raises
- ------
- IndexError:
- When idx > len(self)
- """
- componentType = self.componentType
-
- try:
- currentValue = self._componentValues[idx]
- except IndexError:
- currentValue = noValue
-
- if len(self._componentValues) < idx:
- raise error.PyAsn1Error('Component index out of range')
-
- if value is noValue:
- if componentType is not None:
- value = componentType.clone()
- elif currentValue is noValue:
- raise error.PyAsn1Error('Component type not defined')
- elif not isinstance(value, base.Asn1Item):
- if componentType is not None and isinstance(componentType, base.AbstractSimpleAsn1Item):
- value = componentType.clone(value=value)
- elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
- value = currentValue.clone(value=value)
- else:
- raise error.PyAsn1Error('Non-ASN.1 value %r and undefined component type at %r' % (value, self))
- elif componentType is not None:
- if self.strictConstraints:
- if not componentType.isSameTypeWith(value, matchTags, matchConstraints):
- raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
- else:
- if not componentType.isSuperTypeOf(value, matchTags, matchConstraints):
- raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
-
- if verifyConstraints and value.isValue:
- try:
- self.subtypeSpec(value, idx)
-
- except error.PyAsn1Error:
- exType, exValue, exTb = sys.exc_info()
- raise exType('%s at %s' % (exValue, self.__class__.__name__))
-
- if currentValue is noValue:
- self._componentValues.append(value)
- else:
- self._componentValues[idx] = value
-
- return self
-
- @property
- def componentTagMap(self):
- if self.componentType is not None:
- return self.componentType.tagMap
-
- def prettyPrint(self, scope=0):
- scope += 1
- representation = self.__class__.__name__ + ':\n'
- for idx, componentValue in enumerate(self._componentValues):
- representation += ' ' * scope
- if (componentValue is noValue and
- self.componentType is not None):
- representation += '<empty>'
- else:
- representation += componentValue.prettyPrint(scope)
- return representation
-
- def prettyPrintType(self, scope=0):
- scope += 1
- representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
- if self.componentType is not None:
- representation += ' ' * scope
- representation += self.componentType.prettyPrintType(scope)
- return representation + '\n' + ' ' * (scope - 1) + '}'
-
-
- @property
- def isValue(self):
- """Indicate that |ASN.1| object represents ASN.1 value.
-
- If *isValue* is `False` then this object represents just ASN.1 schema.
-
- If *isValue* is `True` then, in addition to its ASN.1 schema features,
- this object can also be used like a Python built-in object (e.g. `int`,
- `str`, `dict` etc.).
-
- Returns
- -------
- : :class:`bool`
- :class:`False` if object represents just ASN.1 schema.
- :class:`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).
- """
- for componentValue in self._componentValues:
- if componentValue is noValue or not componentValue.isValue:
- return False
-
- return True
-
-
- class SequenceOf(SequenceOfAndSetOfBase):
- __doc__ = SequenceOfAndSetOfBase.__doc__
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- )
-
- #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- #: object representing ASN.1 type allowed within |ASN.1| type
- componentType = None
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
- # Disambiguation ASN.1 types identification
- typeId = SequenceOfAndSetOfBase.getTypeId()
-
-
- class SetOf(SequenceOfAndSetOfBase):
- __doc__ = SequenceOfAndSetOfBase.__doc__
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
- )
-
- #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- #: object representing ASN.1 type allowed within |ASN.1| type
- componentType = None
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
- # Disambiguation ASN.1 types identification
- typeId = SequenceOfAndSetOfBase.getTypeId()
-
-
- class SequenceAndSetBase(base.AbstractConstructedAsn1Item):
- """Create |ASN.1| type.
-
- |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
-
- Keyword Args
- ------------
- componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
- Object holding named ASN.1 types allowed within this collection
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
-
- Examples
- --------
-
- .. code-block:: python
-
- class Description(Sequence): # Set is similar
- '''
- ASN.1 specification:
-
- Description ::= SEQUENCE {
- surname IA5String,
- first-name IA5String OPTIONAL,
- age INTEGER DEFAULT 40
- }
- '''
- componentType = NamedTypes(
- NamedType('surname', IA5String()),
- OptionalNamedType('first-name', IA5String()),
- DefaultedNamedType('age', Integer(40))
- )
-
- descr = Description()
- descr['surname'] = 'Smith'
- descr['first-name'] = 'John'
- """
- #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes`
- #: object representing named ASN.1 types allowed within |ASN.1| type
- componentType = namedtype.NamedTypes()
-
-
- class DynamicNames(object):
- """Fields names/positions mapping for component-less objects"""
- def __init__(self):
- self._keyToIdxMap = {}
- self._idxToKeyMap = {}
-
- def __len__(self):
- return len(self._keyToIdxMap)
-
- def __contains__(self, item):
- return item in self._keyToIdxMap or item in self._idxToKeyMap
-
- def __iter__(self):
- return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap)))
-
- def __getitem__(self, item):
- try:
- return self._keyToIdxMap[item]
-
- except KeyError:
- return self._idxToKeyMap[item]
-
- def getNameByPosition(self, idx):
- try:
- return self._idxToKeyMap[idx]
-
- except KeyError:
- raise error.PyAsn1Error('Type position out of range')
-
- def getPositionByName(self, name):
- try:
- return self._keyToIdxMap[name]
-
- except KeyError:
- raise error.PyAsn1Error('Name %s not found' % (name,))
-
- def addField(self, idx):
- self._keyToIdxMap['field-%d' % idx] = idx
- self._idxToKeyMap[idx] = 'field-%d' % idx
-
-
- def __init__(self, **kwargs):
- base.AbstractConstructedAsn1Item.__init__(self, **kwargs)
- self._componentTypeLen = len(self.componentType)
- self._dynamicNames = self._componentTypeLen or self.DynamicNames()
-
- def __getitem__(self, idx):
- if octets.isStringType(idx):
- try:
- return self.getComponentByName(idx)
-
- except error.PyAsn1Error:
- # duck-typing dict
- raise KeyError(sys.exc_info()[1])
-
- else:
- try:
- return self.getComponentByPosition(idx)
-
- except error.PyAsn1Error:
- # duck-typing list
- raise IndexError(sys.exc_info()[1])
-
- def __setitem__(self, idx, value):
- if octets.isStringType(idx):
- try:
- self.setComponentByName(idx, value)
-
- except error.PyAsn1Error:
- # duck-typing dict
- raise KeyError(sys.exc_info()[1])
-
- else:
- try:
- self.setComponentByPosition(idx, value)
-
- except error.PyAsn1Error:
- # duck-typing list
- raise IndexError(sys.exc_info()[1])
-
- def __contains__(self, key):
- if self._componentTypeLen:
- return key in self.componentType
- else:
- return key in self._dynamicNames
-
- def __iter__(self):
- return iter(self.componentType or self._dynamicNames)
-
- # Python dict protocol
-
- def values(self):
- for idx in range(self._componentTypeLen or len(self._dynamicNames)):
- yield self[idx]
-
- def keys(self):
- return iter(self)
-
- def items(self):
- for idx in range(self._componentTypeLen or len(self._dynamicNames)):
- if self._componentTypeLen:
- yield self.componentType[idx].name, self[idx]
- else:
- yield self._dynamicNames[idx], self[idx]
-
- def update(self, *iterValue, **mappingValue):
- for k, v in iterValue:
- self[k] = v
- for k in mappingValue:
- self[k] = mappingValue[k]
-
- def clear(self):
- self._componentValues = []
- self._dynamicNames = self.DynamicNames()
-
- def _cloneComponentValues(self, myClone, cloneValueFlag):
- for idx, componentValue in enumerate(self._componentValues):
- if componentValue is not noValue:
- if isinstance(componentValue, base.AbstractConstructedAsn1Item):
- myClone.setComponentByPosition(
- idx, componentValue.clone(cloneValueFlag=cloneValueFlag)
- )
- else:
- myClone.setComponentByPosition(idx, componentValue.clone())
-
- def getComponentByName(self, name, default=noValue, instantiate=True):
- """Returns |ASN.1| type component by name.
-
- Equivalent to Python :class:`dict` subscription operation (e.g. `[]`).
-
- Parameters
- ----------
- name: :class:`str`
- |ASN.1| type component name
-
- Keyword Args
- ------------
- default: :class:`object`
- If set and requested component is a schema object, return the `default`
- object instead of the requested component.
-
- instantiate: :class:`bool`
- If `True` (default), inner component will be automatically instantiated.
- If 'False' either existing component or the `noValue` object will be
- returned.
-
- Returns
- -------
- : :py:class:`~pyasn1.type.base.PyAsn1Item`
- Instantiate |ASN.1| component type or return existing component value
- """
- if self._componentTypeLen:
- idx = self.componentType.getPositionByName(name)
- else:
- try:
- idx = self._dynamicNames.getPositionByName(name)
-
- except KeyError:
- raise error.PyAsn1Error('Name %s not found' % (name,))
-
- return self.getComponentByPosition(idx, default=default, instantiate=instantiate)
-
- def setComponentByName(self, name, value=noValue,
- verifyConstraints=True,
- matchTags=True,
- matchConstraints=True):
- """Assign |ASN.1| type component by name.
-
- Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`).
-
- Parameters
- ----------
- name: :class:`str`
- |ASN.1| type component name
-
- Keyword Args
- ------------
- value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A Python value to initialize |ASN.1| component with (if *componentType* is set)
- or ASN.1 value object to assign to |ASN.1| component.
-
- verifyConstraints: :class:`bool`
- If `False`, skip constraints validation
-
- matchTags: :class:`bool`
- If `False`, skip component tags matching
-
- matchConstraints: :class:`bool`
- If `False`, skip component constraints matching
-
- Returns
- -------
- self
- """
- if self._componentTypeLen:
- idx = self.componentType.getPositionByName(name)
- else:
- try:
- idx = self._dynamicNames.getPositionByName(name)
-
- except KeyError:
- raise error.PyAsn1Error('Name %s not found' % (name,))
-
- return self.setComponentByPosition(
- idx, value, verifyConstraints, matchTags, matchConstraints
- )
-
- def getComponentByPosition(self, idx, default=noValue, instantiate=True):
- """Returns |ASN.1| type component by index.
-
- Equivalent to Python sequence subscription operation (e.g. `[]`).
-
- Parameters
- ----------
- idx: :class:`int`
- Component index (zero-based). Must either refer to an existing
- component or (if *componentType* is set) new ASN.1 schema object gets
- instantiated.
-
- Keyword Args
- ------------
- default: :class:`object`
- If set and requested component is a schema object, return the `default`
- object instead of the requested component.
-
- instantiate: :class:`bool`
- If `True` (default), inner component will be automatically instantiated.
- If 'False' either existing component or the `noValue` object will be
- returned.
-
- Returns
- -------
- : :py:class:`~pyasn1.type.base.PyAsn1Item`
- a PyASN1 object
-
- Examples
- --------
-
- .. code-block:: python
-
- # can also be Set
- class MySequence(Sequence):
- componentType = NamedTypes(
- NamedType('id', OctetString())
- )
-
- s = MySequence()
-
- # returns component #0 with `.isValue` property False
- s.getComponentByPosition(0)
-
- # returns None
- s.getComponentByPosition(0, default=None)
-
- s.clear()
-
- # returns noValue
- s.getComponentByPosition(0, instantiate=False)
-
- # sets component #0 to OctetString() ASN.1 schema
- # object and returns it
- s.getComponentByPosition(0, instantiate=True)
-
- # sets component #0 to ASN.1 value object
- s.setComponentByPosition(0, 'ABCD')
-
- # returns OctetString('ABCD') value object
- s.getComponentByPosition(0, instantiate=False)
-
- s.clear()
-
- # returns noValue
- s.getComponentByPosition(0, instantiate=False)
- """
- try:
- componentValue = self._componentValues[idx]
-
- except IndexError:
- componentValue = noValue
-
- if not instantiate:
- if componentValue is noValue or not componentValue.isValue:
- return default
- else:
- return componentValue
-
- if componentValue is noValue:
- self.setComponentByPosition(idx)
-
- componentValue = self._componentValues[idx]
-
- if default is noValue or componentValue.isValue:
- return componentValue
- else:
- return default
-
- def setComponentByPosition(self, idx, value=noValue,
- verifyConstraints=True,
- matchTags=True,
- matchConstraints=True):
- """Assign |ASN.1| type component by position.
-
- Equivalent to Python sequence item assignment operation (e.g. `[]`).
-
- Parameters
- ----------
- idx : :class:`int`
- Component index (zero-based). Must either refer to existing
- component (if *componentType* is set) or to N+1 component
- otherwise. In the latter case a new component of given ASN.1
- type gets instantiated and appended to |ASN.1| sequence.
-
- Keyword Args
- ------------
- value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A Python value to initialize |ASN.1| component with (if *componentType* is set)
- or ASN.1 value object to assign to |ASN.1| component.
-
- verifyConstraints : :class:`bool`
- If `False`, skip constraints validation
-
- matchTags: :class:`bool`
- If `False`, skip component tags matching
-
- matchConstraints: :class:`bool`
- If `False`, skip component constraints matching
-
- Returns
- -------
- self
- """
- componentType = self.componentType
- componentTypeLen = self._componentTypeLen
-
- try:
- currentValue = self._componentValues[idx]
-
- except IndexError:
- currentValue = noValue
- if componentTypeLen:
- if componentTypeLen < idx:
- raise error.PyAsn1Error('component index out of range')
-
- self._componentValues = [noValue] * componentTypeLen
-
- if value is noValue:
- if componentTypeLen:
- value = componentType.getTypeByPosition(idx).clone()
-
- elif currentValue is noValue:
- raise error.PyAsn1Error('Component type not defined')
-
- elif not isinstance(value, base.Asn1Item):
- if componentTypeLen:
- subComponentType = componentType.getTypeByPosition(idx)
- if isinstance(subComponentType, base.AbstractSimpleAsn1Item):
- value = subComponentType.clone(value=value)
-
- else:
- raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__)
-
- elif currentValue is not noValue and isinstance(currentValue, base.AbstractSimpleAsn1Item):
- value = currentValue.clone(value=value)
-
- else:
- raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__)
-
- elif (matchTags or matchConstraints) and componentTypeLen:
- subComponentType = componentType.getTypeByPosition(idx)
- if subComponentType is not noValue:
- subtypeChecker = (self.strictConstraints and
- subComponentType.isSameTypeWith or
- subComponentType.isSuperTypeOf)
-
- if not subtypeChecker(value, matchTags, matchConstraints):
- if not componentType[idx].openType:
- raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType))
-
- if verifyConstraints and value.isValue:
- try:
- self.subtypeSpec(value, idx)
-
- except error.PyAsn1Error:
- exType, exValue, exTb = sys.exc_info()
- raise exType('%s at %s' % (exValue, self.__class__.__name__))
-
- if componentTypeLen or idx in self._dynamicNames:
- self._componentValues[idx] = value
-
- elif len(self._componentValues) == idx:
- self._componentValues.append(value)
- self._dynamicNames.addField(idx)
-
- else:
- raise error.PyAsn1Error('Component index out of range')
-
- return self
-
- @property
- def isValue(self):
- """Indicate that |ASN.1| object represents ASN.1 value.
-
- If *isValue* is `False` then this object represents just ASN.1 schema.
-
- If *isValue* is `True` then, in addition to its ASN.1 schema features,
- this object can also be used like a Python built-in object (e.g. `int`,
- `str`, `dict` etc.).
-
- Returns
- -------
- : :class:`bool`
- :class:`False` if object represents just ASN.1 schema.
- :class:`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).
- """
- componentType = self.componentType
-
- if componentType:
- for idx, subComponentType in enumerate(componentType.namedTypes):
- if subComponentType.isDefaulted or subComponentType.isOptional:
- continue
-
- if not self._componentValues:
- return False
-
- componentValue = self._componentValues[idx]
- if componentValue is noValue or not componentValue.isValue:
- return False
-
- else:
- for componentValue in self._componentValues:
- if componentValue is noValue or not componentValue.isValue:
- return False
-
- return True
-
- def prettyPrint(self, scope=0):
- """Return an object representation string.
-
- Returns
- -------
- : :class:`str`
- Human-friendly object representation.
- """
- scope += 1
- representation = self.__class__.__name__ + ':\n'
- for idx, componentValue in enumerate(self._componentValues):
- if componentValue is not noValue:
- representation += ' ' * scope
- if self.componentType:
- representation += self.componentType.getNameByPosition(idx)
- else:
- representation += self._dynamicNames.getNameByPosition(idx)
- representation = '%s=%s\n' % (
- representation, componentValue.prettyPrint(scope)
- )
- return representation
-
- def prettyPrintType(self, scope=0):
- scope += 1
- representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__)
- for idx, componentType in enumerate(self.componentType.values() or self._componentValues):
- representation += ' ' * scope
- if self.componentType:
- representation += '"%s"' % self.componentType.getNameByPosition(idx)
- else:
- representation += '"%s"' % self._dynamicNames.getNameByPosition(idx)
- representation = '%s = %s\n' % (
- representation, componentType.prettyPrintType(scope)
- )
- return representation + '\n' + ' ' * (scope - 1) + '}'
-
- # backward compatibility
-
- def setDefaultComponents(self):
- return self
-
- def getComponentType(self):
- if self._componentTypeLen:
- return self.componentType
-
- def getNameByPosition(self, idx):
- if self._componentTypeLen:
- return self.componentType[idx].name
-
-
- class Sequence(SequenceAndSetBase):
- __doc__ = SequenceAndSetBase.__doc__
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10)
- )
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing constraints on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
- #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
- #: object imposing size constraint on |ASN.1| objects
- componentType = namedtype.NamedTypes()
-
- # Disambiguation ASN.1 types identification
- typeId = SequenceAndSetBase.getTypeId()
-
- # backward compatibility
-
- def getComponentTagMapNearPosition(self, idx):
- if self.componentType:
- return self.componentType.getTagMapNearPosition(idx)
-
- def getComponentPositionNearType(self, tagSet, idx):
- if self.componentType:
- return self.componentType.getPositionNearType(tagSet, idx)
- else:
- return idx
-
-
- class Set(SequenceAndSetBase):
- __doc__ = SequenceAndSetBase.__doc__
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.initTagSet(
- tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11)
- )
-
- #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
- #: object representing ASN.1 type allowed within |ASN.1| type
- componentType = namedtype.NamedTypes()
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing constraints on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection()
-
- # Disambiguation ASN.1 types identification
- typeId = SequenceAndSetBase.getTypeId()
-
- def getComponent(self, innerFlag=False):
- return self
-
- def getComponentByType(self, tagSet, default=noValue,
- instantiate=True, innerFlag=False):
- """Returns |ASN.1| type component by ASN.1 tag.
-
- Parameters
- ----------
- tagSet : :py:class:`~pyasn1.type.tag.TagSet`
- Object representing ASN.1 tags to identify one of
- |ASN.1| object component
-
- Keyword Args
- ------------
- default: :class:`object`
- If set and requested component is a schema object, return the `default`
- object instead of the requested component.
-
- instantiate: :class:`bool`
- If `True` (default), inner component will be automatically instantiated.
- If 'False' either existing component or the `noValue` object will be
- returned.
-
- Returns
- -------
- : :py:class:`~pyasn1.type.base.PyAsn1Item`
- a pyasn1 object
- """
- componentValue = self.getComponentByPosition(
- self.componentType.getPositionByType(tagSet),
- default=default, instantiate=instantiate
- )
- if innerFlag and isinstance(componentValue, Set):
- # get inner component by inner tagSet
- return componentValue.getComponent(innerFlag=True)
- else:
- # get outer component by inner tagSet
- return componentValue
-
- def setComponentByType(self, tagSet, value=noValue,
- verifyConstraints=True,
- matchTags=True,
- matchConstraints=True,
- innerFlag=False):
- """Assign |ASN.1| type component by ASN.1 tag.
-
- Parameters
- ----------
- tagSet : :py:class:`~pyasn1.type.tag.TagSet`
- Object representing ASN.1 tags to identify one of
- |ASN.1| object component
-
- Keyword Args
- ------------
- value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A Python value to initialize |ASN.1| component with (if *componentType* is set)
- or ASN.1 value object to assign to |ASN.1| component.
-
- verifyConstraints : :class:`bool`
- If `False`, skip constraints validation
-
- matchTags: :class:`bool`
- If `False`, skip component tags matching
-
- matchConstraints: :class:`bool`
- If `False`, skip component constraints matching
-
- innerFlag: :class:`bool`
- If `True`, search for matching *tagSet* recursively.
-
- Returns
- -------
- self
- """
- idx = self.componentType.getPositionByType(tagSet)
-
- if innerFlag: # set inner component by inner tagSet
- componentType = self.componentType.getTypeByPosition(idx)
-
- if componentType.tagSet:
- return self.setComponentByPosition(
- idx, value, verifyConstraints, matchTags, matchConstraints
- )
- else:
- componentType = self.getComponentByPosition(idx)
- return componentType.setComponentByType(
- tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag
- )
- else: # set outer component by inner tagSet
- return self.setComponentByPosition(
- idx, value, verifyConstraints, matchTags, matchConstraints
- )
-
- @property
- def componentTagMap(self):
- if self.componentType:
- return self.componentType.tagMapUnique
-
-
- class Choice(Set):
- """Create |ASN.1| type.
-
- |ASN.1| objects are mutable and duck-type Python :class:`dict` objects.
-
- Keyword Args
- ------------
- componentType: :py:class:`~pyasn1.type.namedtype.NamedType`
- Object holding named ASN.1 types allowed within this collection
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- sizeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing collection size constraint
-
- Examples
- --------
-
- .. code-block:: python
-
- class Afters(Choice):
- '''
- ASN.1 specification:
-
- Afters ::= CHOICE {
- cheese [0] IA5String,
- dessert [1] IA5String
- }
- '''
- componentType = NamedTypes(
- NamedType('cheese', IA5String().subtype(
- implicitTag=Tag(tagClassContext, tagFormatSimple, 0)
- ),
- NamedType('dessert', IA5String().subtype(
- implicitTag=Tag(tagClassContext, tagFormatSimple, 1)
- )
- )
-
- afters = Afters()
- afters['cheese'] = 'Mascarpone'
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.TagSet() # untagged
-
- #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`)
- #: object representing ASN.1 type allowed within |ASN.1| type
- componentType = namedtype.NamedTypes()
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- #: Default :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- #: object imposing size constraint on |ASN.1| objects
- sizeSpec = constraint.ConstraintsIntersection(
- constraint.ValueSizeConstraint(1, 1)
- )
-
- # Disambiguation ASN.1 types identification
- typeId = Set.getTypeId()
-
- _currentIdx = None
-
- def __eq__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] == other
- return NotImplemented
-
- def __ne__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] != other
- return NotImplemented
-
- def __lt__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] < other
- return NotImplemented
-
- def __le__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] <= other
- return NotImplemented
-
- def __gt__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] > other
- return NotImplemented
-
- def __ge__(self, other):
- if self._componentValues:
- return self._componentValues[self._currentIdx] >= other
- return NotImplemented
-
- if sys.version_info[0] <= 2:
- def __nonzero__(self):
- return self._componentValues and True or False
- else:
- def __bool__(self):
- return self._componentValues and True or False
-
- def __len__(self):
- return self._currentIdx is not None and 1 or 0
-
- def __contains__(self, key):
- if self._currentIdx is None:
- return False
- return key == self.componentType[self._currentIdx].getName()
-
- def __iter__(self):
- if self._currentIdx is None:
- raise StopIteration
- yield self.componentType[self._currentIdx].getName()
-
- # Python dict protocol
-
- def values(self):
- if self._currentIdx is not None:
- yield self._componentValues[self._currentIdx]
-
- def keys(self):
- if self._currentIdx is not None:
- yield self.componentType[self._currentIdx].getName()
-
- def items(self):
- if self._currentIdx is not None:
- yield self.componentType[self._currentIdx].getName(), self[self._currentIdx]
-
- def verifySizeSpec(self):
- if self._currentIdx is None:
- raise error.PyAsn1Error('Component not chosen')
-
- def _cloneComponentValues(self, myClone, cloneValueFlag):
- try:
- component = self.getComponent()
- except error.PyAsn1Error:
- pass
- else:
- if isinstance(component, Choice):
- tagSet = component.effectiveTagSet
- else:
- tagSet = component.tagSet
- if isinstance(component, base.AbstractConstructedAsn1Item):
- myClone.setComponentByType(
- tagSet, component.clone(cloneValueFlag=cloneValueFlag)
- )
- else:
- myClone.setComponentByType(tagSet, component.clone())
-
- def getComponentByPosition(self, idx, default=noValue, instantiate=True):
- __doc__ = Set.__doc__
-
- if self._currentIdx is None or self._currentIdx != idx:
- return Set.getComponentByPosition(self, idx, default=default,
- instantiate=instantiate)
-
- return self._componentValues[idx]
-
- def setComponentByPosition(self, idx, value=noValue,
- verifyConstraints=True,
- matchTags=True,
- matchConstraints=True):
- """Assign |ASN.1| type component by position.
-
- Equivalent to Python sequence item assignment operation (e.g. `[]`).
-
- Parameters
- ----------
- idx: :class:`int`
- Component index (zero-based). Must either refer to existing
- component or to N+1 component. In the latter case a new component
- type gets instantiated (if *componentType* is set, or given ASN.1
- object is taken otherwise) and appended to the |ASN.1| sequence.
-
- Keyword Args
- ------------
- value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative
- A Python value to initialize |ASN.1| component with (if *componentType* is set)
- or ASN.1 value object to assign to |ASN.1| component. Once a new value is
- set to *idx* component, previous value is dropped.
-
- verifyConstraints : :class:`bool`
- If `False`, skip constraints validation
-
- matchTags: :class:`bool`
- If `False`, skip component tags matching
-
- matchConstraints: :class:`bool`
- If `False`, skip component constraints matching
-
- Returns
- -------
- self
- """
- oldIdx = self._currentIdx
- Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints)
- self._currentIdx = idx
- if oldIdx is not None and oldIdx != idx:
- self._componentValues[oldIdx] = noValue
- return self
-
- @property
- def effectiveTagSet(self):
- """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged)."""
- if self.tagSet:
- return self.tagSet
- else:
- component = self.getComponent()
- return component.effectiveTagSet
-
- @property
- def tagMap(self):
- """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
- ASN.1 tags to ASN.1 objects contained within callee.
- """
- if self.tagSet:
- return Set.tagMap.fget(self)
- else:
- return self.componentType.tagMapUnique
-
- def getComponent(self, innerFlag=False):
- """Return currently assigned component of the |ASN.1| object.
-
- Returns
- -------
- : :py:class:`~pyasn1.type.base.PyAsn1Item`
- a PyASN1 object
- """
- if self._currentIdx is None:
- raise error.PyAsn1Error('Component not chosen')
- else:
- c = self._componentValues[self._currentIdx]
- if innerFlag and isinstance(c, Choice):
- return c.getComponent(innerFlag)
- else:
- return c
-
- def getName(self, innerFlag=False):
- """Return the name of currently assigned component of the |ASN.1| object.
-
- Returns
- -------
- : :py:class:`str`
- |ASN.1| component name
- """
- if self._currentIdx is None:
- raise error.PyAsn1Error('Component not chosen')
- else:
- if innerFlag:
- c = self._componentValues[self._currentIdx]
- if isinstance(c, Choice):
- return c.getName(innerFlag)
- return self.componentType.getNameByPosition(self._currentIdx)
-
- @property
- def isValue(self):
- """Indicate that |ASN.1| object represents ASN.1 value.
-
- If *isValue* is `False` then this object represents just ASN.1 schema.
-
- If *isValue* is `True` then, in addition to its ASN.1 schema features,
- this object can also be used like a Python built-in object (e.g. `int`,
- `str`, `dict` etc.).
-
- Returns
- -------
- : :class:`bool`
- :class:`False` if object represents just ASN.1 schema.
- :class:`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).
- """
- if self._currentIdx is None:
- return False
-
- componentValue = self._componentValues[self._currentIdx]
-
- return componentValue is not noValue and componentValue.isValue
-
- def clear(self):
- self._currentIdx = None
- Set.clear(self)
-
- # compatibility stubs
-
- def getMinTagSet(self):
- return self.minTagSet
-
-
- class Any(OctetString):
- """Create |ASN.1| schema or value object.
-
- |ASN.1| objects are immutable and duck-type Python 2 :class:`str` or Python 3
- :class:`bytes`. When used in Unicode context, |ASN.1| type assumes "|encoding|"
- serialisation.
-
- Keyword Args
- ------------
- value: :class:`str`, :class:`bytes` or |ASN.1| object
- string (Python 2) or bytes (Python 3), alternatively unicode object
- (Python 2) or string (Python 3) representing character string to be
- serialised into octets (note `encoding` parameter) or |ASN.1| object.
-
- tagSet: :py:class:`~pyasn1.type.tag.TagSet`
- Object representing non-default ASN.1 tag(s)
-
- subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection`
- Object representing non-default ASN.1 subtype constraint(s)
-
- encoding: :py:class:`str`
- Unicode codec ID to encode/decode :class:`unicode` (Python 2) or
- :class:`str` (Python 3) the payload when |ASN.1| object is used
- in text string context.
-
- binValue: :py:class:`str`
- Binary string initializer to use instead of the *value*.
- Example: '10110011'.
-
- hexValue: :py:class:`str`
- Hexadecimal string initializer to use instead of the *value*.
- Example: 'DEADBEEF'.
-
- Raises
- ------
- :py:class:`~pyasn1.error.PyAsn1Error`
- On constraint violation or bad initializer.
-
- Examples
- --------
- .. code-block:: python
-
- class Error(Sequence):
- '''
- ASN.1 specification:
-
- Error ::= SEQUENCE {
- code INTEGER,
- parameter ANY DEFINED BY code -- Either INTEGER or REAL
- }
- '''
- componentType=NamedTypes(
- NamedType('code', Integer()),
- NamedType('parameter', Any(),
- openType=OpenType('code', {1: Integer(),
- 2: Real()}))
- )
-
- error = Error()
- error['code'] = 1
- error['parameter'] = Integer(1234)
- """
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s)
- #: associated with |ASN.1| type.
- tagSet = tag.TagSet() # untagged
-
- #: Set (on class, not on instance) or return a
- #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object
- #: imposing constraints on |ASN.1| type initialization values.
- subtypeSpec = constraint.ConstraintsIntersection()
-
- # Disambiguation ASN.1 types identification
- typeId = OctetString.getTypeId()
-
- @property
- def tagMap(self):
- """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping
- ASN.1 tags to ASN.1 objects contained within callee.
- """
- try:
- return self._tagMap
-
- except AttributeError:
- self._tagMap = tagmap.TagMap(
- {self.tagSet: self},
- {eoo.endOfOctets.tagSet: eoo.endOfOctets},
- self
- )
-
- return self._tagMap
-
- # XXX
- # coercion rules?
|