Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/type/tag.py: 72%
123 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:51 +0000
1#
2# This file is part of pyasn1 software.
3#
4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com>
5# License: https://pyasn1.readthedocs.io/en/latest/license.html
6#
7from pyasn1 import error
9__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext',
10 'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed',
11 'tagCategoryImplicit', 'tagCategoryExplicit',
12 'tagCategoryUntagged', 'Tag', 'TagSet']
14#: Identifier for ASN.1 class UNIVERSAL
15tagClassUniversal = 0x00
17#: Identifier for ASN.1 class APPLICATION
18tagClassApplication = 0x40
20#: Identifier for ASN.1 class context-specific
21tagClassContext = 0x80
23#: Identifier for ASN.1 class private
24tagClassPrivate = 0xC0
26#: Identifier for "simple" ASN.1 structure (e.g. scalar)
27tagFormatSimple = 0x00
29#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components)
30tagFormatConstructed = 0x20
32tagCategoryImplicit = 0x01
33tagCategoryExplicit = 0x02
34tagCategoryUntagged = 0x04
37class Tag(object):
38 """Create ASN.1 tag
40 Represents ASN.1 tag that can be attached to a ASN.1 type to make
41 types distinguishable from each other.
43 *Tag* objects are immutable and duck-type Python :class:`tuple` objects
44 holding three integer components of a tag.
46 Parameters
47 ----------
48 tagClass: :py:class:`int`
49 Tag *class* value
51 tagFormat: :py:class:`int`
52 Tag *format* value
54 tagId: :py:class:`int`
55 Tag ID value
56 """
57 def __init__(self, tagClass, tagFormat, tagId):
58 if tagId < 0:
59 raise error.PyAsn1Error('Negative tag ID (%s) not allowed' % tagId)
60 self.__tagClass = tagClass
61 self.__tagFormat = tagFormat
62 self.__tagId = tagId
63 self.__tagClassId = tagClass, tagId
64 self.__hash = hash(self.__tagClassId)
66 def __repr__(self):
67 representation = '[%s:%s:%s]' % (
68 self.__tagClass, self.__tagFormat, self.__tagId)
69 return '<%s object, tag %s>' % (
70 self.__class__.__name__, representation)
72 def __eq__(self, other):
73 return self.__tagClassId == other
75 def __ne__(self, other):
76 return self.__tagClassId != other
78 def __lt__(self, other):
79 return self.__tagClassId < other
81 def __le__(self, other):
82 return self.__tagClassId <= other
84 def __gt__(self, other):
85 return self.__tagClassId > other
87 def __ge__(self, other):
88 return self.__tagClassId >= other
90 def __hash__(self):
91 return self.__hash
93 def __getitem__(self, idx):
94 if idx == 0:
95 return self.__tagClass
96 elif idx == 1:
97 return self.__tagFormat
98 elif idx == 2:
99 return self.__tagId
100 else:
101 raise IndexError()
103 def __iter__(self):
104 yield self.__tagClass
105 yield self.__tagFormat
106 yield self.__tagId
108 def __and__(self, otherTag):
109 return self.__class__(self.__tagClass & otherTag.tagClass,
110 self.__tagFormat & otherTag.tagFormat,
111 self.__tagId & otherTag.tagId)
113 def __or__(self, otherTag):
114 return self.__class__(self.__tagClass | otherTag.tagClass,
115 self.__tagFormat | otherTag.tagFormat,
116 self.__tagId | otherTag.tagId)
118 @property
119 def tagClass(self):
120 """ASN.1 tag class
122 Returns
123 -------
124 : :py:class:`int`
125 Tag class
126 """
127 return self.__tagClass
129 @property
130 def tagFormat(self):
131 """ASN.1 tag format
133 Returns
134 -------
135 : :py:class:`int`
136 Tag format
137 """
138 return self.__tagFormat
140 @property
141 def tagId(self):
142 """ASN.1 tag ID
144 Returns
145 -------
146 : :py:class:`int`
147 Tag ID
148 """
149 return self.__tagId
152class TagSet(object):
153 """Create a collection of ASN.1 tags
155 Represents a combination of :class:`~pyasn1.type.tag.Tag` objects
156 that can be attached to a ASN.1 type to make types distinguishable
157 from each other.
159 *TagSet* objects are immutable and duck-type Python :class:`tuple` objects
160 holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects.
162 Parameters
163 ----------
164 baseTag: :class:`~pyasn1.type.tag.Tag`
165 Base *Tag* object. This tag survives IMPLICIT tagging.
167 *superTags: :class:`~pyasn1.type.tag.Tag`
168 Additional *Tag* objects taking part in subtyping.
170 Examples
171 --------
172 .. code-block:: python
174 class OrderNumber(NumericString):
175 '''
176 ASN.1 specification
178 Order-number ::=
179 [APPLICATION 5] IMPLICIT NumericString
180 '''
181 tagSet = NumericString.tagSet.tagImplicitly(
182 Tag(tagClassApplication, tagFormatSimple, 5)
183 )
185 orderNumber = OrderNumber('1234')
186 """
187 def __init__(self, baseTag=(), *superTags):
188 self.__baseTag = baseTag
189 self.__superTags = superTags
190 self.__superTagsClassId = tuple(
191 [(superTag.tagClass, superTag.tagId) for superTag in superTags]
192 )
193 self.__lenOfSuperTags = len(superTags)
194 self.__hash = hash(self.__superTagsClassId)
196 def __repr__(self):
197 representation = '-'.join(['%s:%s:%s' % (x.tagClass, x.tagFormat, x.tagId)
198 for x in self.__superTags])
199 if representation:
200 representation = 'tags ' + representation
201 else:
202 representation = 'untagged'
204 return '<%s object, %s>' % (self.__class__.__name__, representation)
206 def __add__(self, superTag):
207 return self.__class__(self.__baseTag, *self.__superTags + (superTag,))
209 def __radd__(self, superTag):
210 return self.__class__(self.__baseTag, *(superTag,) + self.__superTags)
212 def __getitem__(self, i):
213 if i.__class__ is slice:
214 return self.__class__(self.__baseTag, *self.__superTags[i])
215 else:
216 return self.__superTags[i]
218 def __eq__(self, other):
219 return self.__superTagsClassId == other
221 def __ne__(self, other):
222 return self.__superTagsClassId != other
224 def __lt__(self, other):
225 return self.__superTagsClassId < other
227 def __le__(self, other):
228 return self.__superTagsClassId <= other
230 def __gt__(self, other):
231 return self.__superTagsClassId > other
233 def __ge__(self, other):
234 return self.__superTagsClassId >= other
236 def __hash__(self):
237 return self.__hash
239 def __len__(self):
240 return self.__lenOfSuperTags
242 @property
243 def baseTag(self):
244 """Return base ASN.1 tag
246 Returns
247 -------
248 : :class:`~pyasn1.type.tag.Tag`
249 Base tag of this *TagSet*
250 """
251 return self.__baseTag
253 @property
254 def superTags(self):
255 """Return ASN.1 tags
257 Returns
258 -------
259 : :py:class:`tuple`
260 Tuple of :class:`~pyasn1.type.tag.Tag` objects that this *TagSet* contains
261 """
262 return self.__superTags
264 def tagExplicitly(self, superTag):
265 """Return explicitly tagged *TagSet*
267 Create a new *TagSet* representing callee *TagSet* explicitly tagged
268 with passed tag(s). With explicit tagging mode, new tags are appended
269 to existing tag(s).
271 Parameters
272 ----------
273 superTag: :class:`~pyasn1.type.tag.Tag`
274 *Tag* object to tag this *TagSet*
276 Returns
277 -------
278 : :class:`~pyasn1.type.tag.TagSet`
279 New *TagSet* object
280 """
281 if superTag.tagClass == tagClassUniversal:
282 raise error.PyAsn1Error("Can't tag with UNIVERSAL class tag")
283 if superTag.tagFormat != tagFormatConstructed:
284 superTag = Tag(superTag.tagClass, tagFormatConstructed, superTag.tagId)
285 return self + superTag
287 def tagImplicitly(self, superTag):
288 """Return implicitly tagged *TagSet*
290 Create a new *TagSet* representing callee *TagSet* implicitly tagged
291 with passed tag(s). With implicit tagging mode, new tag(s) replace the
292 last existing tag.
294 Parameters
295 ----------
296 superTag: :class:`~pyasn1.type.tag.Tag`
297 *Tag* object to tag this *TagSet*
299 Returns
300 -------
301 : :class:`~pyasn1.type.tag.TagSet`
302 New *TagSet* object
303 """
304 if self.__superTags:
305 superTag = Tag(superTag.tagClass, self.__superTags[-1].tagFormat, superTag.tagId)
306 return self[:-1] + superTag
308 def isSuperTagSetOf(self, tagSet):
309 """Test type relationship against given *TagSet*
311 The callee is considered to be a supertype of given *TagSet*
312 tag-wise if all tags in *TagSet* are present in the callee and
313 they are in the same order.
315 Parameters
316 ----------
317 tagSet: :class:`~pyasn1.type.tag.TagSet`
318 *TagSet* object to evaluate against the callee
320 Returns
321 -------
322 : :py:class:`bool`
323 :obj:`True` if callee is a supertype of *tagSet*
324 """
325 if len(tagSet) < self.__lenOfSuperTags:
326 return False
327 return self.__superTags == tagSet[:self.__lenOfSuperTags]
329 # Backward compatibility
331 def getBaseTag(self):
332 return self.__baseTag
334def initTagSet(tag):
335 return TagSet(tag, tag)