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:45 +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 

8 

9__all__ = ['tagClassUniversal', 'tagClassApplication', 'tagClassContext', 

10 'tagClassPrivate', 'tagFormatSimple', 'tagFormatConstructed', 

11 'tagCategoryImplicit', 'tagCategoryExplicit', 

12 'tagCategoryUntagged', 'Tag', 'TagSet'] 

13 

14#: Identifier for ASN.1 class UNIVERSAL 

15tagClassUniversal = 0x00 

16 

17#: Identifier for ASN.1 class APPLICATION 

18tagClassApplication = 0x40 

19 

20#: Identifier for ASN.1 class context-specific 

21tagClassContext = 0x80 

22 

23#: Identifier for ASN.1 class private 

24tagClassPrivate = 0xC0 

25 

26#: Identifier for "simple" ASN.1 structure (e.g. scalar) 

27tagFormatSimple = 0x00 

28 

29#: Identifier for "constructed" ASN.1 structure (e.g. may have inner components) 

30tagFormatConstructed = 0x20 

31 

32tagCategoryImplicit = 0x01 

33tagCategoryExplicit = 0x02 

34tagCategoryUntagged = 0x04 

35 

36 

37class Tag(object): 

38 """Create ASN.1 tag 

39 

40 Represents ASN.1 tag that can be attached to a ASN.1 type to make 

41 types distinguishable from each other. 

42 

43 *Tag* objects are immutable and duck-type Python :class:`tuple` objects 

44 holding three integer components of a tag. 

45 

46 Parameters 

47 ---------- 

48 tagClass: :py:class:`int` 

49 Tag *class* value 

50 

51 tagFormat: :py:class:`int` 

52 Tag *format* value 

53 

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) 

65 

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) 

71 

72 def __eq__(self, other): 

73 return self.__tagClassId == other 

74 

75 def __ne__(self, other): 

76 return self.__tagClassId != other 

77 

78 def __lt__(self, other): 

79 return self.__tagClassId < other 

80 

81 def __le__(self, other): 

82 return self.__tagClassId <= other 

83 

84 def __gt__(self, other): 

85 return self.__tagClassId > other 

86 

87 def __ge__(self, other): 

88 return self.__tagClassId >= other 

89 

90 def __hash__(self): 

91 return self.__hash 

92 

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() 

102 

103 def __iter__(self): 

104 yield self.__tagClass 

105 yield self.__tagFormat 

106 yield self.__tagId 

107 

108 def __and__(self, otherTag): 

109 return self.__class__(self.__tagClass & otherTag.tagClass, 

110 self.__tagFormat & otherTag.tagFormat, 

111 self.__tagId & otherTag.tagId) 

112 

113 def __or__(self, otherTag): 

114 return self.__class__(self.__tagClass | otherTag.tagClass, 

115 self.__tagFormat | otherTag.tagFormat, 

116 self.__tagId | otherTag.tagId) 

117 

118 @property 

119 def tagClass(self): 

120 """ASN.1 tag class 

121 

122 Returns 

123 ------- 

124 : :py:class:`int` 

125 Tag class 

126 """ 

127 return self.__tagClass 

128 

129 @property 

130 def tagFormat(self): 

131 """ASN.1 tag format 

132 

133 Returns 

134 ------- 

135 : :py:class:`int` 

136 Tag format 

137 """ 

138 return self.__tagFormat 

139 

140 @property 

141 def tagId(self): 

142 """ASN.1 tag ID 

143 

144 Returns 

145 ------- 

146 : :py:class:`int` 

147 Tag ID 

148 """ 

149 return self.__tagId 

150 

151 

152class TagSet(object): 

153 """Create a collection of ASN.1 tags 

154 

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. 

158 

159 *TagSet* objects are immutable and duck-type Python :class:`tuple` objects 

160 holding arbitrary number of :class:`~pyasn1.type.tag.Tag` objects. 

161 

162 Parameters 

163 ---------- 

164 baseTag: :class:`~pyasn1.type.tag.Tag` 

165 Base *Tag* object. This tag survives IMPLICIT tagging. 

166 

167 *superTags: :class:`~pyasn1.type.tag.Tag` 

168 Additional *Tag* objects taking part in subtyping. 

169 

170 Examples 

171 -------- 

172 .. code-block:: python 

173 

174 class OrderNumber(NumericString): 

175 ''' 

176 ASN.1 specification 

177 

178 Order-number ::= 

179 [APPLICATION 5] IMPLICIT NumericString 

180 ''' 

181 tagSet = NumericString.tagSet.tagImplicitly( 

182 Tag(tagClassApplication, tagFormatSimple, 5) 

183 ) 

184 

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) 

195 

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' 

203 

204 return '<%s object, %s>' % (self.__class__.__name__, representation) 

205 

206 def __add__(self, superTag): 

207 return self.__class__(self.__baseTag, *self.__superTags + (superTag,)) 

208 

209 def __radd__(self, superTag): 

210 return self.__class__(self.__baseTag, *(superTag,) + self.__superTags) 

211 

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] 

217 

218 def __eq__(self, other): 

219 return self.__superTagsClassId == other 

220 

221 def __ne__(self, other): 

222 return self.__superTagsClassId != other 

223 

224 def __lt__(self, other): 

225 return self.__superTagsClassId < other 

226 

227 def __le__(self, other): 

228 return self.__superTagsClassId <= other 

229 

230 def __gt__(self, other): 

231 return self.__superTagsClassId > other 

232 

233 def __ge__(self, other): 

234 return self.__superTagsClassId >= other 

235 

236 def __hash__(self): 

237 return self.__hash 

238 

239 def __len__(self): 

240 return self.__lenOfSuperTags 

241 

242 @property 

243 def baseTag(self): 

244 """Return base ASN.1 tag 

245 

246 Returns 

247 ------- 

248 : :class:`~pyasn1.type.tag.Tag` 

249 Base tag of this *TagSet* 

250 """ 

251 return self.__baseTag 

252 

253 @property 

254 def superTags(self): 

255 """Return ASN.1 tags 

256 

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 

263 

264 def tagExplicitly(self, superTag): 

265 """Return explicitly tagged *TagSet* 

266 

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). 

270 

271 Parameters 

272 ---------- 

273 superTag: :class:`~pyasn1.type.tag.Tag` 

274 *Tag* object to tag this *TagSet* 

275 

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 

286 

287 def tagImplicitly(self, superTag): 

288 """Return implicitly tagged *TagSet* 

289 

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. 

293 

294 Parameters 

295 ---------- 

296 superTag: :class:`~pyasn1.type.tag.Tag` 

297 *Tag* object to tag this *TagSet* 

298 

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 

307 

308 def isSuperTagSetOf(self, tagSet): 

309 """Test type relationship against given *TagSet* 

310 

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. 

314 

315 Parameters 

316 ---------- 

317 tagSet: :class:`~pyasn1.type.tag.TagSet` 

318 *TagSet* object to evaluate against the callee 

319 

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] 

328 

329 # Backward compatibility 

330 

331 def getBaseTag(self): 

332 return self.__baseTag 

333 

334def initTagSet(tag): 

335 return TagSet(tag, tag)