/usr/share/doc/python-pyasn1/constructed.html is in python-pyasn1 0.1.9-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 | <html>
<title>
PyASN1 Constructed types
</title>
<head>
</head>
<body>
<center>
<table width=60%>
<tr>
<td>
<h4>
1.3 PyASN1 Constructed types
</h4>
<p>
Besides scalar types, ASN.1 specifies so-called constructed ones - these
are capable of holding one or more values of other types, both scalar
and constructed.
</p>
<p>
In pyasn1 implementation, constructed ASN.1 types behave like
Python sequences, and also support additional component addressing methods,
specific to particular constructed type.
</p>
<a name="1.3.1"></a>
<h4>
1.3.1 Sequence and Set types
</h4>
<p>
The Sequence and Set types have many similar properties:
</p>
<ul>
<li>they can hold any number of inner components of different types
<li>every component has a human-friendly identifier
<li>any component can have a default value
<li>some components can be absent.
</ul>
<p>
However, Sequence type guarantees the ordering of Sequence value components
to match their declaration order. By contrast, components of the
Set type can be ordered to best suite application's needs.
<p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
Record ::= SEQUENCE {
id INTEGER,
room [0] INTEGER OPTIONAL,
house [1] INTEGER DEFAULT 0
}
</pre>
</td></tr></table>
<p>
Up to this moment, the only method we used for creating new pyasn1 types
is Python sub-classing. With this method, a new, named Python class is created
what mimics type derivation in ASN.1 grammar. However, ASN.1 also allows for
defining anonymous subtypes (room and house components in the example above).
To support anonymous subtyping in pyasn1, a cloning operation on an existing
pyasn1 type object can be invoked what creates a new instance of original
object with possibly modified properties.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> from pyasn1.type import univ, namedtype, tag
>>> class Record(univ.Sequence):
... componentType = namedtype.NamedTypes(
... namedtype.NamedType('id', univ.Integer()),
... namedtype.OptionalNamedType(
... 'room',
... univ.Integer().subtype(
... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
... )
... ),
... namedtype.DefaultedNamedType(
... 'house',
... univ.Integer(0).subtype(
... implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
... )
... )
... )
>>>
</pre>
</td></tr></table>
<p>
All pyasn1 constructed type classes have a class attribute <b>componentType</b>
that represent default type specification. Its value is a NamedTypes object.
</p>
<p>
The NamedTypes class instance holds a sequence of NameType, OptionalNamedType
or DefaultedNamedType objects which, in turn, refer to pyasn1 type objects that
represent inner SEQUENCE components specification.
</p>
<p>
Finally, invocation of a subtype() method of pyasn1 type objects in the code
above returns an implicitly tagged copy of original object.
</p>
<p>
Once a SEQUENCE or SET type is decleared with pyasn1, it can be instantiated
and initialized (continuing the above code):
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> record = Record()
>>> record.setComponentByName('id', 123)
>>> print(record.prettyPrint())
Record:
id=123
>>>
>>> record.setComponentByPosition(1, 321)
>>> print(record.prettyPrint())
Record:
id=123
room=321
>>>
>>> record.setDefaultComponents()
>>> print(record.prettyPrint())
Record:
id=123
room=321
house=0
</pre>
</td></tr></table>
<p>
Inner components of pyasn1 Sequence/Set objects could be accessed using the
following methods:
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> record.getComponentByName('id')
Integer(123)
>>> record.getComponentByPosition(1)
Integer(321)
>>> record[2]
Integer(0)
>>> for idx in range(len(record)):
... print(record.getNameByPosition(idx), record.getComponentByPosition(idx))
id 123
room 321
house 0
>>>
</pre>
</td></tr></table>
<p>
The Set type share all the properties of Sequence type, and additionally
support by-tag component addressing (as all Set components have distinct
types).
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> from pyasn1.type import univ, namedtype, tag
>>> class Gamer(univ.Set):
... componentType = namedtype.NamedTypes(
... namedtype.NamedType('score', univ.Integer()),
... namedtype.NamedType('player', univ.OctetString()),
... namedtype.NamedType('id', univ.ObjectIdentifier())
... )
>>> gamer = Gamer()
>>> gamer.setComponentByType(univ.Integer().getTagSet(), 121343)
>>> gamer.setComponentByType(univ.OctetString().getTagSet(), 'Pascal')
>>> gamer.setComponentByType(univ.ObjectIdentifier().getTagSet(), (1,3,7,2))
>>> print(gamer.prettyPrint())
Gamer:
score=121343
player=b'Pascal'
id=1.3.7.2
>>>
</pre>
</td></tr></table>
<a name="1.3.2"></a>
<h4>
1.3.2 SequenceOf and SetOf types
</h4>
<p>
Both, SequenceOf and SetOf types resemble an unlimited size list of components.
All the components must be of the same type.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
Progression ::= SEQUENCE OF INTEGER
arithmeticProgression Progression ::= { 1, 3, 5, 7 }
</pre>
</td></tr></table>
<p>
SequenceOf and SetOf types are expressed by the very similar pyasn1 type
objects. Their components can only be addressed by position and they
both have a property of automatic resize.
</p>
<p>
To specify inner component type, the <b>componentType</b> class attribute
should refer to another pyasn1 type object.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> from pyasn1.type import univ
>>> class Progression(univ.SequenceOf):
... componentType = univ.Integer()
>>> arithmeticProgression = Progression()
>>> arithmeticProgression.setComponentByPosition(1, 111)
>>> print(arithmeticProgression.prettyPrint())
Progression:
-empty- 111
>>> arithmeticProgression.setComponentByPosition(0, 100)
>>> print(arithmeticProgression.prettyPrint())
Progression:
100 111
>>>
>>> for idx in range(len(arithmeticProgression)):
... arithmeticProgression.getComponentByPosition(idx)
Integer(100)
Integer(111)
>>>
</pre>
</td></tr></table>
<p>
Any scalar or constructed pyasn1 type object can serve as an inner component.
Missing components are prohibited in SequenceOf/SetOf value objects.
</p>
<a name="1.3.3"></a>
<h4>
1.3.3 Choice type
</h4>
<p>
Values of ASN.1 CHOICE type can contain only a single value of a type from a
list of possible alternatives. Alternatives must be ASN.1 types with
distinct tags for the whole structure to remain unambiguous. Unlike most
other types, CHOICE is an untagged one, e.g. it has no base tag of its own.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
CodeOrMessage ::= CHOICE {
code INTEGER,
message OCTET STRING
}
</pre>
</td></tr></table>
<p>
In pyasn1 implementation, Choice object behaves like Set but accepts only
a single inner component at a time. It also offers a few additional methods
specific to its behaviour.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> from pyasn1.type import univ, namedtype
>>> class CodeOrMessage(univ.Choice):
... componentType = namedtype.NamedTypes(
... namedtype.NamedType('code', univ.Integer()),
... namedtype.NamedType('message', univ.OctetString())
... )
>>>
>>> codeOrMessage = CodeOrMessage()
>>> print(codeOrMessage.prettyPrint())
CodeOrMessage:
>>> codeOrMessage.setComponentByName('code', 123)
>>> print(codeOrMessage.prettyPrint())
CodeOrMessage:
code=123
>>> codeOrMessage.setComponentByName('message', 'my string value')
>>> print(codeOrMessage.prettyPrint())
CodeOrMessage:
message=b'my string value'
>>>
</pre>
</td></tr></table>
<p>
Since there could be only a single inner component value in the pyasn1 Choice
value object, either of the following methods could be used for fetching it
(continuing previous code):
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> codeOrMessage.getName()
'message'
>>> codeOrMessage.getComponent()
OctetString(b'my string value')
>>>
</pre>
</td></tr></table>
<a name="1.3.4"></a>
<h4>
1.3.4 Any type
</h4>
<p>
The ASN.1 ANY type is a kind of wildcard or placeholder that matches
any other type without knowing it in advance. Like CHOICE type, ANY
has no base tag.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
Error ::= SEQUENCE {
code INTEGER,
parameter ANY DEFINED BY code
}
</pre>
</td></tr></table>
<p>
The ANY type is frequently used in specifications, where exact type is not
yet agreed upon between communicating parties or the number of possible
alternatives of a type is infinite.
Sometimes an auxiliary selector is kept around to help parties indicate
the kind of ANY payload in effect ("code" in the example above).
</p>
<p>
Values of the ANY type contain serialized ASN.1 value(s) in form of
an octet string. Therefore pyasn1 Any value object share the properties of
pyasn1 OctetString object.
</p>
<table bgcolor="lightgray" border=0 width=100%><TR><TD>
<pre>
>>> from pyasn1.type import univ
>>> someValue = univ.Any(b'\x02\x01\x01')
>>> someValue
Any(b'\x02\x01\x01')
>>> str(someValue)
'\x02\x01\x01'
>>> bytes(someValue)
b'\x02\x01\x01'
>>>
</pre>
</td></tr></table>
<p>
Receiving application is supposed to explicitly deserialize the content of Any
value object, possibly using auxiliary selector for figuring out its ASN.1
type to pick appropriate decoder.
</p>
<p>
There will be some more talk and code snippets covering Any type in the codecs
chapters that follow.
</p>
<hr>
</td>
</tr>
</table>
</center>
</body>
</html>
|