1# Base classes for ASN.1 types 2import sys 3from pyasn1.type import constraint, tagmap 4from pyasn1 import error 5 6class Asn1Item: pass 7 8class Asn1ItemBase(Asn1Item): 9 # Set of tags for this ASN.1 type 10 tagSet = () 11 12 # A list of constraint.Constraint instances for checking values 13 subtypeSpec = constraint.ConstraintsIntersection() 14 15 # Used for ambiguous ASN.1 types identification 16 typeId = None 17 18 def __init__(self, tagSet=None, subtypeSpec=None): 19 if tagSet is None: 20 self._tagSet = self.tagSet 21 else: 22 self._tagSet = tagSet 23 if subtypeSpec is None: 24 self._subtypeSpec = self.subtypeSpec 25 else: 26 self._subtypeSpec = subtypeSpec 27 28 def _verifySubtypeSpec(self, value, idx=None): 29 try: 30 self._subtypeSpec(value, idx) 31 except error.PyAsn1Error: 32 c, i, t = sys.exc_info() 33 raise c('%s at %s' % (i, self.__class__.__name__)) 34 35 def getSubtypeSpec(self): return self._subtypeSpec 36 37 def getTagSet(self): return self._tagSet 38 def getEffectiveTagSet(self): return self._tagSet # used by untagged types 39 def getTagMap(self): return tagmap.TagMap({self._tagSet: self}) 40 41 def isSameTypeWith(self, other): 42 return self is other or \ 43 self._tagSet == other.getTagSet() and \ 44 self._subtypeSpec == other.getSubtypeSpec() 45 def isSuperTypeOf(self, other): 46 """Returns true if argument is a ASN1 subtype of ourselves""" 47 return self._tagSet.isSuperTagSetOf(other.getTagSet()) and \ 48 self._subtypeSpec.isSuperTypeOf(other.getSubtypeSpec()) 49 50class __NoValue: 51 def __getattr__(self, attr): 52 raise error.PyAsn1Error('No value for %s()' % attr) 53 def __getitem__(self, i): 54 raise error.PyAsn1Error('No value') 55 56noValue = __NoValue() 57 58# Base class for "simple" ASN.1 objects. These are immutable. 59class AbstractSimpleAsn1Item(Asn1ItemBase): 60 defaultValue = noValue 61 def __init__(self, value=None, tagSet=None, subtypeSpec=None): 62 Asn1ItemBase.__init__(self, tagSet, subtypeSpec) 63 if value is None or value is noValue: 64 value = self.defaultValue 65 if value is None or value is noValue: 66 self.__hashedValue = value = noValue 67 else: 68 value = self.prettyIn(value) 69 self._verifySubtypeSpec(value) 70 self.__hashedValue = hash(value) 71 self._value = value 72 self._len = None 73 74 def __repr__(self): 75 if self._value is noValue: 76 return self.__class__.__name__ + '()' 77 else: 78 return self.__class__.__name__ + '(%s)' % (self.prettyOut(self._value),) 79 def __str__(self): return str(self._value) 80 def __eq__(self, other): 81 return self is other and True or self._value == other 82 def __ne__(self, other): return self._value != other 83 def __lt__(self, other): return self._value < other 84 def __le__(self, other): return self._value <= other 85 def __gt__(self, other): return self._value > other 86 def __ge__(self, other): return self._value >= other 87 if sys.version_info[0] <= 2: 88 def __nonzero__(self): return bool(self._value) 89 else: 90 def __bool__(self): return bool(self._value) 91 def __hash__(self): return self.__hashedValue 92 93 def clone(self, value=None, tagSet=None, subtypeSpec=None): 94 if value is None and tagSet is None and subtypeSpec is None: 95 return self 96 if value is None: 97 value = self._value 98 if tagSet is None: 99 tagSet = self._tagSet 100 if subtypeSpec is None: 101 subtypeSpec = self._subtypeSpec 102 return self.__class__(value, tagSet, subtypeSpec) 103 104 def subtype(self, value=None, implicitTag=None, explicitTag=None, 105 subtypeSpec=None): 106 if value is None: 107 value = self._value 108 if implicitTag is not None: 109 tagSet = self._tagSet.tagImplicitly(implicitTag) 110 elif explicitTag is not None: 111 tagSet = self._tagSet.tagExplicitly(explicitTag) 112 else: 113 tagSet = self._tagSet 114 if subtypeSpec is None: 115 subtypeSpec = self._subtypeSpec 116 else: 117 subtypeSpec = subtypeSpec + self._subtypeSpec 118 return self.__class__(value, tagSet, subtypeSpec) 119 120 def prettyIn(self, value): return value 121 def prettyOut(self, value): return str(value) 122 123 def prettyPrint(self, scope=0): 124 if self._value is noValue: 125 return '<no value>' 126 else: 127 return self.prettyOut(self._value) 128 129 # XXX Compatibility stub 130 def prettyPrinter(self, scope=0): return self.prettyPrint(scope) 131 132# 133# Constructed types: 134# * There are five of them: Sequence, SequenceOf/SetOf, Set and Choice 135# * ASN1 types and values are represened by Python class instances 136# * Value initialization is made for defaulted components only 137# * Primary method of component addressing is by-position. Data model for base 138# type is Python sequence. Additional type-specific addressing methods 139# may be implemented for particular types. 140# * SequenceOf and SetOf types do not implement any additional methods 141# * Sequence, Set and Choice types also implement by-identifier addressing 142# * Sequence, Set and Choice types also implement by-asn1-type (tag) addressing 143# * Sequence and Set types may include optional and defaulted 144# components 145# * Constructed types hold a reference to component types used for value 146# verification and ordering. 147# * Component type is a scalar type for SequenceOf/SetOf types and a list 148# of types for Sequence/Set/Choice. 149# 150 151class AbstractConstructedAsn1Item(Asn1ItemBase): 152 componentType = None 153 sizeSpec = constraint.ConstraintsIntersection() 154 def __init__(self, componentType=None, tagSet=None, 155 subtypeSpec=None, sizeSpec=None): 156 Asn1ItemBase.__init__(self, tagSet, subtypeSpec) 157 if componentType is None: 158 self._componentType = self.componentType 159 else: 160 self._componentType = componentType 161 if sizeSpec is None: 162 self._sizeSpec = self.sizeSpec 163 else: 164 self._sizeSpec = sizeSpec 165 self._componentValues = [] 166 self._componentValuesSet = 0 167 168 def __repr__(self): 169 r = self.__class__.__name__ + '()' 170 for idx in range(len(self._componentValues)): 171 if self._componentValues[idx] is None: 172 continue 173 r = r + '.setComponentByPosition(%s, %r)' % ( 174 idx, self._componentValues[idx] 175 ) 176 return r 177 178 def __eq__(self, other): 179 return self is other and True or self._componentValues == other 180 def __ne__(self, other): return self._componentValues != other 181 def __lt__(self, other): return self._componentValues < other 182 def __le__(self, other): return self._componentValues <= other 183 def __gt__(self, other): return self._componentValues > other 184 def __ge__(self, other): return self._componentValues >= other 185 if sys.version_info[0] <= 2: 186 def __nonzero__(self): return bool(self._componentValues) 187 else: 188 def __bool__(self): return bool(self._componentValues) 189 190 def getComponentTagMap(self): 191 raise error.PyAsn1Error('Method not implemented') 192 193 def _cloneComponentValues(self, myClone, cloneValueFlag): pass 194 195 def clone(self, tagSet=None, subtypeSpec=None, sizeSpec=None, 196 cloneValueFlag=None): 197 if tagSet is None: 198 tagSet = self._tagSet 199 if subtypeSpec is None: 200 subtypeSpec = self._subtypeSpec 201 if sizeSpec is None: 202 sizeSpec = self._sizeSpec 203 r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec) 204 if cloneValueFlag: 205 self._cloneComponentValues(r, cloneValueFlag) 206 return r 207 208 def subtype(self, implicitTag=None, explicitTag=None, subtypeSpec=None, 209 sizeSpec=None, cloneValueFlag=None): 210 if implicitTag is not None: 211 tagSet = self._tagSet.tagImplicitly(implicitTag) 212 elif explicitTag is not None: 213 tagSet = self._tagSet.tagExplicitly(explicitTag) 214 else: 215 tagSet = self._tagSet 216 if subtypeSpec is None: 217 subtypeSpec = self._subtypeSpec 218 else: 219 subtypeSpec = subtypeSpec + self._subtypeSpec 220 if sizeSpec is None: 221 sizeSpec = self._sizeSpec 222 else: 223 sizeSpec = sizeSpec + self._sizeSpec 224 r = self.__class__(self._componentType, tagSet, subtypeSpec, sizeSpec) 225 if cloneValueFlag: 226 self._cloneComponentValues(r, cloneValueFlag) 227 return r 228 229 def _verifyComponent(self, idx, value): pass 230 231 def verifySizeSpec(self): self._sizeSpec(self) 232 233 def getComponentByPosition(self, idx): 234 raise error.PyAsn1Error('Method not implemented') 235 def setComponentByPosition(self, idx, value, verifyConstraints=True): 236 raise error.PyAsn1Error('Method not implemented') 237 238 def getComponentType(self): return self._componentType 239 240 def __getitem__(self, idx): return self.getComponentByPosition(idx) 241 def __setitem__(self, idx, value): self.setComponentByPosition(idx, value) 242 243 def __len__(self): return len(self._componentValues) 244 245 def clear(self): 246 self._componentValues = [] 247 self._componentValuesSet = 0 248 249 def setDefaultComponents(self): pass 250