1# ASN.1 types tags 2from operator import getitem 3from pyasn1 import error 4 5tagClassUniversal = 0x00 6tagClassApplication = 0x40 7tagClassContext = 0x80 8tagClassPrivate = 0xC0 9 10tagFormatSimple = 0x00 11tagFormatConstructed = 0x20 12 13tagCategoryImplicit = 0x01 14tagCategoryExplicit = 0x02 15tagCategoryUntagged = 0x04 16 17class Tag: 18 def __init__(self, tagClass, tagFormat, tagId): 19 if tagId < 0: 20 raise error.PyAsn1Error( 21 'Negative tag ID (%s) not allowed' % (tagId,) 22 ) 23 self.__tag = (tagClass, tagFormat, tagId) 24 self.uniq = (tagClass, tagId) 25 self.__hashedUniqTag = hash(self.uniq) 26 27 def __repr__(self): 28 return '%s(tagClass=%s, tagFormat=%s, tagId=%s)' % ( 29 (self.__class__.__name__,) + self.__tag 30 ) 31 # These is really a hotspot -- expose public "uniq" attribute to save on 32 # function calls 33 def __eq__(self, other): return self.uniq == other.uniq 34 def __ne__(self, other): return self.uniq != other.uniq 35 def __lt__(self, other): return self.uniq < other.uniq 36 def __le__(self, other): return self.uniq <= other.uniq 37 def __gt__(self, other): return self.uniq > other.uniq 38 def __ge__(self, other): return self.uniq >= other.uniq 39 def __hash__(self): return self.__hashedUniqTag 40 def __getitem__(self, idx): return self.__tag[idx] 41 def __and__(self, otherTag): 42 (tagClass, tagFormat, tagId) = otherTag 43 return self.__class__( 44 self.__tag&tagClass, self.__tag&tagFormat, self.__tag&tagId 45 ) 46 def __or__(self, otherTag): 47 (tagClass, tagFormat, tagId) = otherTag 48 return self.__class__( 49 self.__tag[0]|tagClass, 50 self.__tag[1]|tagFormat, 51 self.__tag[2]|tagId 52 ) 53 def asTuple(self): return self.__tag # __getitem__() is slow 54 55class TagSet: 56 def __init__(self, baseTag=(), *superTags): 57 self.__baseTag = baseTag 58 self.__superTags = superTags 59 self.__hashedSuperTags = hash(superTags) 60 _uniq = () 61 for t in superTags: 62 _uniq = _uniq + t.uniq 63 self.uniq = _uniq 64 self.__lenOfSuperTags = len(superTags) 65 66 def __repr__(self): 67 return '%s(%s)' % ( 68 self.__class__.__name__, 69 ', '.join([repr(x) for x in self.__superTags]) 70 ) 71 72 def __add__(self, superTag): 73 return self.__class__( 74 self.__baseTag, *self.__superTags + (superTag,) 75 ) 76 def __radd__(self, superTag): 77 return self.__class__( 78 self.__baseTag, *(superTag,) + self.__superTags 79 ) 80 81 def tagExplicitly(self, superTag): 82 tagClass, tagFormat, tagId = superTag 83 if tagClass == tagClassUniversal: 84 raise error.PyAsn1Error( 85 'Can\'t tag with UNIVERSAL-class tag' 86 ) 87 if tagFormat != tagFormatConstructed: 88 superTag = Tag(tagClass, tagFormatConstructed, tagId) 89 return self + superTag 90 91 def tagImplicitly(self, superTag): 92 tagClass, tagFormat, tagId = superTag 93 if self.__superTags: 94 superTag = Tag(tagClass, self.__superTags[-1][1], tagId) 95 return self[:-1] + superTag 96 97 def getBaseTag(self): return self.__baseTag 98 def __getitem__(self, idx): 99 if isinstance(idx, slice): 100 return self.__class__( 101 self.__baseTag, *getitem(self.__superTags, idx) 102 ) 103 return self.__superTags[idx] 104 def __eq__(self, other): return self.uniq == other.uniq 105 def __ne__(self, other): return self.uniq != other.uniq 106 def __lt__(self, other): return self.uniq < other.uniq 107 def __le__(self, other): return self.uniq <= other.uniq 108 def __gt__(self, other): return self.uniq > other.uniq 109 def __ge__(self, other): return self.uniq >= other.uniq 110 def __hash__(self): return self.__hashedSuperTags 111 def __len__(self): return self.__lenOfSuperTags 112 def isSuperTagSetOf(self, tagSet): 113 if len(tagSet) < self.__lenOfSuperTags: 114 return 115 idx = self.__lenOfSuperTags - 1 116 while idx >= 0: 117 if self.__superTags[idx] != tagSet[idx]: 118 return 119 idx = idx - 1 120 return 1 121 122def initTagSet(tag): return TagSet(tag, tag) 123