1 # NamedType specification for constructed types
3 from pyasn1
.type import tagmap
4 from pyasn1
import error
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
21 class OptionalNamedType(NamedType
):
23 class DefaultedNamedType(NamedType
):
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
= {}
36 r
= '%s(' % self
.__class
__.__name
__
37 for n
in self
.__namedTypes
:
41 def __getitem__(self
, idx
): return self
.__namedTypes
[idx
]
43 if sys
.version_info
[0] <= 2:
44 def __nonzero__(self
): return bool(self
.__namedTypesLen
)
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')
53 return self
.__namedTypes
[idx
].getType()
55 def getPositionByType(self
, tagSet
):
56 if not self
.__tagToPosIdx
:
57 idx
= self
.__namedTypesLen
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
66 return self
.__tagToPosIdx
[tagSet
]
68 raise error
.PyAsn1Error('Type %s not found' % (tagSet
,))
70 def getNameByPosition(self
, idx
):
72 return self
.__namedTypes
[idx
].getName()
74 raise error
.PyAsn1Error('Type position out of range')
75 def getPositionByName(self
, name
):
76 if not self
.__nameToPosIdx
:
77 idx
= self
.__namedTypesLen
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
85 return self
.__nameToPosIdx
[name
]
87 raise error
.PyAsn1Error('Name %s not found' % (name
,))
89 def __buildAmbigiousTagMap(self
):
91 idx
= self
.__namedTypesLen
94 t
= self
.__namedTypes
[idx
]
95 if t
.isOptional
or t
.isDefaulted
:
96 ambigiousTypes
= (t
, ) + ambigiousTypes
98 ambigiousTypes
= (t
, )
99 self
.__ambigiousTypes
[idx
] = NamedTypes(*ambigiousTypes
)
101 def getTagMapNearPosition(self
, idx
):
102 if not self
.__ambigiousTypes
: self
.__buildAmbigiousTagMap
()
104 return self
.__ambigiousTypes
[idx
].getTagMap()
106 raise error
.PyAsn1Error('Type position out of range')
108 def getPositionNearType(self
, tagSet
, idx
):
109 if not self
.__ambigiousTypes
: self
.__buildAmbigiousTagMap
()
111 return idx
+self
.__ambigiousTypes
[idx
].getPositionByType(tagSet
)
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
:
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
]