App Engine Python SDK version 1.8.9
[gae.git] / python / lib / pyasn1 / pyasn1 / type / namedtype.py
blob48967a5fe2230dccb8a4600245c4545291e294c7
1 # NamedType specification for constructed types
2 import sys
3 from pyasn1.type import tagmap
4 from pyasn1 import error
6 class NamedType:
7 isOptional = 0
8 isDefaulted = 0
9 def __init__(self, name, t):
10 self.__name = name; self.__type = t
11 def __repr__(self): return '%s(%s, %s)' % (
12 self.__class__.__name__, self.__name, self.__type
14 def getType(self): return self.__type
15 def getName(self): return self.__name
16 def __getitem__(self, idx):
17 if idx == 0: return self.__name
18 if idx == 1: return self.__type
19 raise IndexError()
21 class OptionalNamedType(NamedType):
22 isOptional = 1
23 class DefaultedNamedType(NamedType):
24 isDefaulted = 1
26 class NamedTypes:
27 def __init__(self, *namedTypes):
28 self.__namedTypes = namedTypes
29 self.__namedTypesLen = len(self.__namedTypes)
30 self.__minTagSet = None
31 self.__tagToPosIdx = {}; self.__nameToPosIdx = {}
32 self.__tagMap = { False: None, True: None }
33 self.__ambigiousTypes = {}
35 def __repr__(self):
36 r = '%s(' % self.__class__.__name__
37 for n in self.__namedTypes:
38 r = r + '%r, ' % (n,)
39 return r + ')'
41 def __getitem__(self, idx): return self.__namedTypes[idx]
43 if sys.version_info[0] <= 2:
44 def __nonzero__(self): return bool(self.__namedTypesLen)
45 else:
46 def __bool__(self): return bool(self.__namedTypesLen)
47 def __len__(self): return self.__namedTypesLen
49 def getTypeByPosition(self, idx):
50 if idx < 0 or idx >= self.__namedTypesLen:
51 raise error.PyAsn1Error('Type position out of range')
52 else:
53 return self.__namedTypes[idx].getType()
55 def getPositionByType(self, tagSet):
56 if not self.__tagToPosIdx:
57 idx = self.__namedTypesLen
58 while idx > 0:
59 idx = idx - 1
60 tagMap = self.__namedTypes[idx].getType().getTagMap()
61 for t in tagMap.getPosMap():
62 if t in self.__tagToPosIdx:
63 raise error.PyAsn1Error('Duplicate type %s' % (t,))
64 self.__tagToPosIdx[t] = idx
65 try:
66 return self.__tagToPosIdx[tagSet]
67 except KeyError:
68 raise error.PyAsn1Error('Type %s not found' % (tagSet,))
70 def getNameByPosition(self, idx):
71 try:
72 return self.__namedTypes[idx].getName()
73 except IndexError:
74 raise error.PyAsn1Error('Type position out of range')
75 def getPositionByName(self, name):
76 if not self.__nameToPosIdx:
77 idx = self.__namedTypesLen
78 while idx > 0:
79 idx = idx - 1
80 n = self.__namedTypes[idx].getName()
81 if n in self.__nameToPosIdx:
82 raise error.PyAsn1Error('Duplicate name %s' % (n,))
83 self.__nameToPosIdx[n] = idx
84 try:
85 return self.__nameToPosIdx[name]
86 except KeyError:
87 raise error.PyAsn1Error('Name %s not found' % (name,))
89 def __buildAmbigiousTagMap(self):
90 ambigiousTypes = ()
91 idx = self.__namedTypesLen
92 while idx > 0:
93 idx = idx - 1
94 t = self.__namedTypes[idx]
95 if t.isOptional or t.isDefaulted:
96 ambigiousTypes = (t, ) + ambigiousTypes
97 else:
98 ambigiousTypes = (t, )
99 self.__ambigiousTypes[idx] = NamedTypes(*ambigiousTypes)
101 def getTagMapNearPosition(self, idx):
102 if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
103 try:
104 return self.__ambigiousTypes[idx].getTagMap()
105 except KeyError:
106 raise error.PyAsn1Error('Type position out of range')
108 def getPositionNearType(self, tagSet, idx):
109 if not self.__ambigiousTypes: self.__buildAmbigiousTagMap()
110 try:
111 return idx+self.__ambigiousTypes[idx].getPositionByType(tagSet)
112 except KeyError:
113 raise error.PyAsn1Error('Type position out of range')
115 def genMinTagSet(self):
116 if self.__minTagSet is None:
117 for t in self.__namedTypes:
118 __type = t.getType()
119 tagSet = getattr(__type,'getMinTagSet',__type.getTagSet)()
120 if self.__minTagSet is None or tagSet < self.__minTagSet:
121 self.__minTagSet = tagSet
122 return self.__minTagSet
124 def getTagMap(self, uniq=False):
125 if self.__tagMap[uniq] is None:
126 tagMap = tagmap.TagMap()
127 for nt in self.__namedTypes:
128 tagMap = tagMap.clone(
129 nt.getType(), nt.getType().getTagMap(), uniq
131 self.__tagMap[uniq] = tagMap
132 return self.__tagMap[uniq]