Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pyasn1/type/univ.py: 39%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1242 statements  

1# 

2# This file is part of pyasn1 software. 

3# 

4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> 

5# License: https://pyasn1.readthedocs.io/en/latest/license.html 

6# 

7import math 

8import sys 

9 

10from pyasn1 import error 

11from pyasn1.codec.ber import eoo 

12from pyasn1.compat import integer 

13from pyasn1.type import base 

14from pyasn1.type import constraint 

15from pyasn1.type import namedtype 

16from pyasn1.type import namedval 

17from pyasn1.type import tag 

18from pyasn1.type import tagmap 

19 

20NoValue = base.NoValue 

21noValue = NoValue() 

22 

23__all__ = ['Integer', 'Boolean', 'BitString', 'OctetString', 'Null', 

24 'ObjectIdentifier', 'Real', 'Enumerated', 

25 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf', 

26 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any', 

27 'NoValue', 'noValue'] 

28 

29# "Simple" ASN.1 types (yet incomplete) 

30 

31 

32class Integer(base.SimpleAsn1Type): 

33 """Create |ASN.1| schema or value object. 

34 

35 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

36 objects are immutable and duck-type Python :class:`int` objects. 

37 

38 Keyword Args 

39 ------------ 

40 value: :class:`int`, :class:`str` or |ASN.1| object 

41 Python :class:`int` or :class:`str` literal or |ASN.1| class 

42 instance. If `value` is not given, schema object will be created. 

43 

44 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

45 Object representing non-default ASN.1 tag(s) 

46 

47 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

48 Object representing non-default ASN.1 subtype constraint(s). Constraints 

49 verification for |ASN.1| type occurs automatically on object 

50 instantiation. 

51 

52 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 

53 Object representing non-default symbolic aliases for numbers 

54 

55 Raises 

56 ------ 

57 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

58 On constraint violation or bad initializer. 

59 

60 Examples 

61 -------- 

62 

63 .. code-block:: python 

64 

65 class ErrorCode(Integer): 

66 ''' 

67 ASN.1 specification: 

68 

69 ErrorCode ::= 

70 INTEGER { disk-full(1), no-disk(-1), 

71 disk-not-formatted(2) } 

72 

73 error ErrorCode ::= disk-full 

74 ''' 

75 namedValues = NamedValues( 

76 ('disk-full', 1), ('no-disk', -1), 

77 ('disk-not-formatted', 2) 

78 ) 

79 

80 error = ErrorCode('disk-full') 

81 """ 

82 #: Set (on class, not on instance) or return a 

83 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

84 #: associated with |ASN.1| type. 

85 tagSet = tag.initTagSet( 

86 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x02) 

87 ) 

88 

89 #: Set (on class, not on instance) or return a 

90 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

91 #: imposing constraints on |ASN.1| type initialization values. 

92 subtypeSpec = constraint.ConstraintsIntersection() 

93 

94 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 

95 #: representing symbolic aliases for numbers 

96 namedValues = namedval.NamedValues() 

97 

98 # Optimization for faster codec lookup 

99 typeId = base.SimpleAsn1Type.getTypeId() 

100 

101 def __init__(self, value=noValue, **kwargs): 

102 if 'namedValues' not in kwargs: 

103 kwargs['namedValues'] = self.namedValues 

104 

105 base.SimpleAsn1Type.__init__(self, value, **kwargs) 

106 

107 def __and__(self, value): 

108 return self.clone(self._value & value) 

109 

110 def __rand__(self, value): 

111 return self.clone(value & self._value) 

112 

113 def __or__(self, value): 

114 return self.clone(self._value | value) 

115 

116 def __ror__(self, value): 

117 return self.clone(value | self._value) 

118 

119 def __xor__(self, value): 

120 return self.clone(self._value ^ value) 

121 

122 def __rxor__(self, value): 

123 return self.clone(value ^ self._value) 

124 

125 def __lshift__(self, value): 

126 return self.clone(self._value << value) 

127 

128 def __rshift__(self, value): 

129 return self.clone(self._value >> value) 

130 

131 def __add__(self, value): 

132 return self.clone(self._value + value) 

133 

134 def __radd__(self, value): 

135 return self.clone(value + self._value) 

136 

137 def __sub__(self, value): 

138 return self.clone(self._value - value) 

139 

140 def __rsub__(self, value): 

141 return self.clone(value - self._value) 

142 

143 def __mul__(self, value): 

144 return self.clone(self._value * value) 

145 

146 def __rmul__(self, value): 

147 return self.clone(value * self._value) 

148 

149 def __mod__(self, value): 

150 return self.clone(self._value % value) 

151 

152 def __rmod__(self, value): 

153 return self.clone(value % self._value) 

154 

155 def __pow__(self, value, modulo=None): 

156 return self.clone(pow(self._value, value, modulo)) 

157 

158 def __rpow__(self, value): 

159 return self.clone(pow(value, self._value)) 

160 

161 def __floordiv__(self, value): 

162 return self.clone(self._value // value) 

163 

164 def __rfloordiv__(self, value): 

165 return self.clone(value // self._value) 

166 

167 def __truediv__(self, value): 

168 return Real(self._value / value) 

169 

170 def __rtruediv__(self, value): 

171 return Real(value / self._value) 

172 

173 def __divmod__(self, value): 

174 return self.clone(divmod(self._value, value)) 

175 

176 def __rdivmod__(self, value): 

177 return self.clone(divmod(value, self._value)) 

178 

179 __hash__ = base.SimpleAsn1Type.__hash__ 

180 

181 def __int__(self): 

182 return int(self._value) 

183 

184 def __float__(self): 

185 return float(self._value) 

186 

187 def __abs__(self): 

188 return self.clone(abs(self._value)) 

189 

190 def __index__(self): 

191 return int(self._value) 

192 

193 def __pos__(self): 

194 return self.clone(+self._value) 

195 

196 def __neg__(self): 

197 return self.clone(-self._value) 

198 

199 def __invert__(self): 

200 return self.clone(~self._value) 

201 

202 def __round__(self, n=0): 

203 r = round(self._value, n) 

204 if n: 

205 return self.clone(r) 

206 else: 

207 return r 

208 

209 def __floor__(self): 

210 return math.floor(self._value) 

211 

212 def __ceil__(self): 

213 return math.ceil(self._value) 

214 

215 def __trunc__(self): 

216 return self.clone(math.trunc(self._value)) 

217 

218 def __lt__(self, value): 

219 return self._value < value 

220 

221 def __le__(self, value): 

222 return self._value <= value 

223 

224 def __eq__(self, value): 

225 return self._value == value 

226 

227 def __ne__(self, value): 

228 return self._value != value 

229 

230 def __gt__(self, value): 

231 return self._value > value 

232 

233 def __ge__(self, value): 

234 return self._value >= value 

235 

236 def prettyIn(self, value): 

237 try: 

238 return int(value) 

239 

240 except ValueError: 

241 try: 

242 return self.namedValues[value] 

243 

244 except KeyError as exc: 

245 raise error.PyAsn1Error( 

246 'Can\'t coerce %r into integer: %s' % (value, exc) 

247 ) 

248 

249 def prettyOut(self, value): 

250 try: 

251 return str(self.namedValues[value]) 

252 

253 except KeyError: 

254 return str(value) 

255 

256 # backward compatibility 

257 

258 def getNamedValues(self): 

259 return self.namedValues 

260 

261 

262class Boolean(Integer): 

263 """Create |ASN.1| schema or value object. 

264 

265 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

266 objects are immutable and duck-type Python :class:`int` objects. 

267 

268 Keyword Args 

269 ------------ 

270 value: :class:`int`, :class:`str` or |ASN.1| object 

271 Python :class:`int` or :class:`str` literal or |ASN.1| class 

272 instance. If `value` is not given, schema object will be created. 

273 

274 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

275 Object representing non-default ASN.1 tag(s) 

276 

277 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

278 Object representing non-default ASN.1 subtype constraint(s).Constraints 

279 verification for |ASN.1| type occurs automatically on object 

280 instantiation. 

281 

282 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 

283 Object representing non-default symbolic aliases for numbers 

284 

285 Raises 

286 ------ 

287 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

288 On constraint violation or bad initializer. 

289 

290 Examples 

291 -------- 

292 .. code-block:: python 

293 

294 class RoundResult(Boolean): 

295 ''' 

296 ASN.1 specification: 

297 

298 RoundResult ::= BOOLEAN 

299 

300 ok RoundResult ::= TRUE 

301 ko RoundResult ::= FALSE 

302 ''' 

303 ok = RoundResult(True) 

304 ko = RoundResult(False) 

305 """ 

306 #: Set (on class, not on instance) or return a 

307 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

308 #: associated with |ASN.1| type. 

309 tagSet = tag.initTagSet( 

310 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x01), 

311 ) 

312 

313 #: Set (on class, not on instance) or return a 

314 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

315 #: imposing constraints on |ASN.1| type initialization values. 

316 subtypeSpec = Integer.subtypeSpec + constraint.SingleValueConstraint(0, 1) 

317 

318 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 

319 #: representing symbolic aliases for numbers 

320 namedValues = namedval.NamedValues(('False', 0), ('True', 1)) 

321 

322 # Optimization for faster codec lookup 

323 typeId = Integer.getTypeId() 

324 

325 

326class SizedInteger(int): 

327 bitLength = leadingZeroBits = None 

328 

329 def setBitLength(self, bitLength): 

330 self.bitLength = bitLength 

331 self.leadingZeroBits = max(bitLength - self.bit_length(), 0) 

332 return self 

333 

334 def __len__(self): 

335 if self.bitLength is None: 

336 self.setBitLength(self.bit_length()) 

337 

338 return self.bitLength 

339 

340 

341class BitString(base.SimpleAsn1Type): 

342 """Create |ASN.1| schema or value object. 

343 

344 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

345 objects are immutable and duck-type both Python :class:`tuple` (as a tuple 

346 of bits) and :class:`int` objects. 

347 

348 Keyword Args 

349 ------------ 

350 value: :class:`int`, :class:`str` or |ASN.1| object 

351 Python :class:`int` or :class:`str` literal representing binary 

352 or hexadecimal number or sequence of integer bits or |ASN.1| object. 

353 If `value` is not given, schema object will be created. 

354 

355 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

356 Object representing non-default ASN.1 tag(s) 

357 

358 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

359 Object representing non-default ASN.1 subtype constraint(s). Constraints 

360 verification for |ASN.1| type occurs automatically on object 

361 instantiation. 

362 

363 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 

364 Object representing non-default symbolic aliases for numbers 

365 

366 binValue: :py:class:`str` 

367 Binary string initializer to use instead of the *value*. 

368 Example: '10110011'. 

369 

370 hexValue: :py:class:`str` 

371 Hexadecimal string initializer to use instead of the *value*. 

372 Example: 'DEADBEEF'. 

373 

374 Raises 

375 ------ 

376 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

377 On constraint violation or bad initializer. 

378 

379 Examples 

380 -------- 

381 .. code-block:: python 

382 

383 class Rights(BitString): 

384 ''' 

385 ASN.1 specification: 

386 

387 Rights ::= BIT STRING { user-read(0), user-write(1), 

388 group-read(2), group-write(3), 

389 other-read(4), other-write(5) } 

390 

391 group1 Rights ::= { group-read, group-write } 

392 group2 Rights ::= '0011'B 

393 group3 Rights ::= '3'H 

394 ''' 

395 namedValues = NamedValues( 

396 ('user-read', 0), ('user-write', 1), 

397 ('group-read', 2), ('group-write', 3), 

398 ('other-read', 4), ('other-write', 5) 

399 ) 

400 

401 group1 = Rights(('group-read', 'group-write')) 

402 group2 = Rights('0011') 

403 group3 = Rights(0x3) 

404 """ 

405 #: Set (on class, not on instance) or return a 

406 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

407 #: associated with |ASN.1| type. 

408 tagSet = tag.initTagSet( 

409 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x03) 

410 ) 

411 

412 #: Set (on class, not on instance) or return a 

413 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

414 #: imposing constraints on |ASN.1| type initialization values. 

415 subtypeSpec = constraint.ConstraintsIntersection() 

416 

417 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 

418 #: representing symbolic aliases for numbers 

419 namedValues = namedval.NamedValues() 

420 

421 # Optimization for faster codec lookup 

422 typeId = base.SimpleAsn1Type.getTypeId() 

423 

424 defaultBinValue = defaultHexValue = noValue 

425 

426 def __init__(self, value=noValue, **kwargs): 

427 if value is noValue: 

428 if kwargs: 

429 try: 

430 value = self.fromBinaryString(kwargs.pop('binValue'), internalFormat=True) 

431 

432 except KeyError: 

433 pass 

434 

435 try: 

436 value = self.fromHexString(kwargs.pop('hexValue'), internalFormat=True) 

437 

438 except KeyError: 

439 pass 

440 

441 if value is noValue: 

442 if self.defaultBinValue is not noValue: 

443 value = self.fromBinaryString(self.defaultBinValue, internalFormat=True) 

444 

445 elif self.defaultHexValue is not noValue: 

446 value = self.fromHexString(self.defaultHexValue, internalFormat=True) 

447 

448 if 'namedValues' not in kwargs: 

449 kwargs['namedValues'] = self.namedValues 

450 

451 base.SimpleAsn1Type.__init__(self, value, **kwargs) 

452 

453 def __str__(self): 

454 return self.asBinary() 

455 

456 def __eq__(self, other): 

457 other = self.prettyIn(other) 

458 return self is other or self._value == other and len(self._value) == len(other) 

459 

460 def __ne__(self, other): 

461 other = self.prettyIn(other) 

462 return self._value != other or len(self._value) != len(other) 

463 

464 def __lt__(self, other): 

465 other = self.prettyIn(other) 

466 return len(self._value) < len(other) or len(self._value) == len(other) and self._value < other 

467 

468 def __le__(self, other): 

469 other = self.prettyIn(other) 

470 return len(self._value) <= len(other) or len(self._value) == len(other) and self._value <= other 

471 

472 def __gt__(self, other): 

473 other = self.prettyIn(other) 

474 return len(self._value) > len(other) or len(self._value) == len(other) and self._value > other 

475 

476 def __ge__(self, other): 

477 other = self.prettyIn(other) 

478 return len(self._value) >= len(other) or len(self._value) == len(other) and self._value >= other 

479 

480 # Immutable sequence object protocol 

481 

482 def __len__(self): 

483 return len(self._value) 

484 

485 def __getitem__(self, i): 

486 if i.__class__ is slice: 

487 return self.clone([self[x] for x in range(*i.indices(len(self)))]) 

488 else: 

489 length = len(self._value) - 1 

490 if i > length or i < 0: 

491 raise IndexError('bit index out of range') 

492 return (self._value >> (length - i)) & 1 

493 

494 def __iter__(self): 

495 length = len(self._value) 

496 while length: 

497 length -= 1 

498 yield (self._value >> length) & 1 

499 

500 def __reversed__(self): 

501 return reversed(tuple(self)) 

502 

503 # arithmetic operators 

504 

505 def __add__(self, value): 

506 value = self.prettyIn(value) 

507 return self.clone(SizedInteger(self._value << len(value) | value).setBitLength(len(self._value) + len(value))) 

508 

509 def __radd__(self, value): 

510 value = self.prettyIn(value) 

511 return self.clone(SizedInteger(value << len(self._value) | self._value).setBitLength(len(self._value) + len(value))) 

512 

513 def __mul__(self, value): 

514 bitString = self._value 

515 while value > 1: 

516 bitString <<= len(self._value) 

517 bitString |= self._value 

518 value -= 1 

519 return self.clone(bitString) 

520 

521 def __rmul__(self, value): 

522 return self * value 

523 

524 def __lshift__(self, count): 

525 return self.clone(SizedInteger(self._value << count).setBitLength(len(self._value) + count)) 

526 

527 def __rshift__(self, count): 

528 return self.clone(SizedInteger(self._value >> count).setBitLength(max(0, len(self._value) - count))) 

529 

530 def __int__(self): 

531 return int(self._value) 

532 

533 def __float__(self): 

534 return float(self._value) 

535 

536 def asNumbers(self): 

537 """Get |ASN.1| value as a sequence of 8-bit integers. 

538 

539 If |ASN.1| object length is not a multiple of 8, result 

540 will be left-padded with zeros. 

541 """ 

542 return tuple(self.asOctets()) 

543 

544 def asOctets(self): 

545 """Get |ASN.1| value as a sequence of octets. 

546 

547 If |ASN.1| object length is not a multiple of 8, result 

548 will be left-padded with zeros. 

549 """ 

550 return integer.to_bytes(self._value, length=len(self)) 

551 

552 def asInteger(self): 

553 """Get |ASN.1| value as a single integer value. 

554 """ 

555 return self._value 

556 

557 def asBinary(self): 

558 """Get |ASN.1| value as a text string of bits. 

559 """ 

560 binString = bin(self._value)[2:] 

561 return '0' * (len(self._value) - len(binString)) + binString 

562 

563 @classmethod 

564 def fromHexString(cls, value, internalFormat=False, prepend=None): 

565 """Create a |ASN.1| object initialized from the hex string. 

566 

567 Parameters 

568 ---------- 

569 value: :class:`str` 

570 Text string like 'DEADBEEF' 

571 """ 

572 try: 

573 value = SizedInteger(value, 16).setBitLength(len(value) * 4) 

574 

575 except ValueError as exc: 

576 raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, exc)) 

577 

578 if prepend is not None: 

579 value = SizedInteger( 

580 (SizedInteger(prepend) << len(value)) | value 

581 ).setBitLength(len(prepend) + len(value)) 

582 

583 if not internalFormat: 

584 value = cls(value) 

585 

586 return value 

587 

588 @classmethod 

589 def fromBinaryString(cls, value, internalFormat=False, prepend=None): 

590 """Create a |ASN.1| object initialized from a string of '0' and '1'. 

591 

592 Parameters 

593 ---------- 

594 value: :class:`str` 

595 Text string like '1010111' 

596 """ 

597 try: 

598 value = SizedInteger(value or '0', 2).setBitLength(len(value)) 

599 

600 except ValueError as exc: 

601 raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, exc)) 

602 

603 if prepend is not None: 

604 value = SizedInteger( 

605 (SizedInteger(prepend) << len(value)) | value 

606 ).setBitLength(len(prepend) + len(value)) 

607 

608 if not internalFormat: 

609 value = cls(value) 

610 

611 return value 

612 

613 @classmethod 

614 def fromOctetString(cls, value, internalFormat=False, prepend=None, padding=0): 

615 """Create a |ASN.1| object initialized from a string. 

616 

617 Parameters 

618 ---------- 

619 value: :class:`bytes` 

620 Text string like b'\\\\x01\\\\xff' 

621 """ 

622 value = SizedInteger(int.from_bytes(bytes(value), 'big') >> padding).setBitLength(len(value) * 8 - padding) 

623 

624 if prepend is not None: 

625 value = SizedInteger( 

626 (SizedInteger(prepend) << len(value)) | value 

627 ).setBitLength(len(prepend) + len(value)) 

628 

629 if not internalFormat: 

630 value = cls(value) 

631 

632 return value 

633 

634 def prettyIn(self, value): 

635 if isinstance(value, SizedInteger): 

636 return value 

637 elif isinstance(value, str): 

638 if not value: 

639 return SizedInteger(0).setBitLength(0) 

640 

641 elif value[0] == '\'': # "'1011'B" -- ASN.1 schema representation (deprecated) 

642 if value[-2:] == '\'B': 

643 return self.fromBinaryString(value[1:-2], internalFormat=True) 

644 elif value[-2:] == '\'H': 

645 return self.fromHexString(value[1:-2], internalFormat=True) 

646 else: 

647 raise error.PyAsn1Error( 

648 'Bad BIT STRING value notation %s' % (value,) 

649 ) 

650 

651 elif self.namedValues and not value.isdigit(): # named bits like 'Urgent, Active' 

652 names = [x.strip() for x in value.split(',')] 

653 

654 try: 

655 

656 bitPositions = [self.namedValues[name] for name in names] 

657 

658 except KeyError: 

659 raise error.PyAsn1Error('unknown bit name(s) in %r' % (names,)) 

660 

661 rightmostPosition = max(bitPositions) 

662 

663 number = 0 

664 for bitPosition in bitPositions: 

665 number |= 1 << (rightmostPosition - bitPosition) 

666 

667 return SizedInteger(number).setBitLength(rightmostPosition + 1) 

668 

669 elif value.startswith('0x'): 

670 return self.fromHexString(value[2:], internalFormat=True) 

671 

672 elif value.startswith('0b'): 

673 return self.fromBinaryString(value[2:], internalFormat=True) 

674 

675 else: # assume plain binary string like '1011' 

676 return self.fromBinaryString(value, internalFormat=True) 

677 

678 elif isinstance(value, (tuple, list)): 

679 return self.fromBinaryString(''.join([b and '1' or '0' for b in value]), internalFormat=True) 

680 

681 elif isinstance(value, BitString): 

682 return SizedInteger(value).setBitLength(len(value)) 

683 

684 elif isinstance(value, int): 

685 return SizedInteger(value) 

686 

687 else: 

688 raise error.PyAsn1Error( 

689 'Bad BitString initializer type \'%s\'' % (value,) 

690 ) 

691 

692 

693class OctetString(base.SimpleAsn1Type): 

694 """Create |ASN.1| schema or value object. 

695 

696 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

697 objects are immutable and duck-type :class:`bytes`. 

698 When used in Unicode context, |ASN.1| type 

699 assumes "|encoding|" serialisation. 

700 

701 Keyword Args 

702 ------------ 

703 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object 

704 :class:`bytes`, alternatively :class:`str` 

705 representing character string to be serialised into octets 

706 (note `encoding` parameter) or |ASN.1| object. 

707 If `value` is not given, schema object will be created. 

708 

709 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

710 Object representing non-default ASN.1 tag(s) 

711 

712 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

713 Object representing non-default ASN.1 subtype constraint(s). Constraints 

714 verification for |ASN.1| type occurs automatically on object 

715 instantiation. 

716 

717 encoding: :py:class:`str` 

718 Unicode codec ID to encode/decode 

719 :class:`str` the payload when |ASN.1| object is used 

720 in text string context. 

721 

722 binValue: :py:class:`str` 

723 Binary string initializer to use instead of the *value*. 

724 Example: '10110011'. 

725 

726 hexValue: :py:class:`str` 

727 Hexadecimal string initializer to use instead of the *value*. 

728 Example: 'DEADBEEF'. 

729 

730 Raises 

731 ------ 

732 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

733 On constraint violation or bad initializer. 

734 

735 Examples 

736 -------- 

737 .. code-block:: python 

738 

739 class Icon(OctetString): 

740 ''' 

741 ASN.1 specification: 

742 

743 Icon ::= OCTET STRING 

744 

745 icon1 Icon ::= '001100010011001000110011'B 

746 icon2 Icon ::= '313233'H 

747 ''' 

748 icon1 = Icon.fromBinaryString('001100010011001000110011') 

749 icon2 = Icon.fromHexString('313233') 

750 """ 

751 #: Set (on class, not on instance) or return a 

752 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

753 #: associated with |ASN.1| type. 

754 tagSet = tag.initTagSet( 

755 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x04) 

756 ) 

757 

758 #: Set (on class, not on instance) or return a 

759 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

760 #: imposing constraints on |ASN.1| type initialization values. 

761 subtypeSpec = constraint.ConstraintsIntersection() 

762 

763 # Optimization for faster codec lookup 

764 typeId = base.SimpleAsn1Type.getTypeId() 

765 

766 defaultBinValue = defaultHexValue = noValue 

767 encoding = 'iso-8859-1' 

768 

769 def __init__(self, value=noValue, **kwargs): 

770 if kwargs: 

771 if value is noValue: 

772 try: 

773 value = self.fromBinaryString(kwargs.pop('binValue')) 

774 

775 except KeyError: 

776 pass 

777 

778 try: 

779 value = self.fromHexString(kwargs.pop('hexValue')) 

780 

781 except KeyError: 

782 pass 

783 

784 if value is noValue: 

785 if self.defaultBinValue is not noValue: 

786 value = self.fromBinaryString(self.defaultBinValue) 

787 

788 elif self.defaultHexValue is not noValue: 

789 value = self.fromHexString(self.defaultHexValue) 

790 

791 if 'encoding' not in kwargs: 

792 kwargs['encoding'] = self.encoding 

793 

794 base.SimpleAsn1Type.__init__(self, value, **kwargs) 

795 

796 def prettyIn(self, value): 

797 if isinstance(value, bytes): 

798 return value 

799 

800 elif isinstance(value, str): 

801 try: 

802 return value.encode(self.encoding) 

803 

804 except UnicodeEncodeError as exc: 

805 raise error.PyAsn1UnicodeEncodeError( 

806 "Can't encode string '%s' with '%s' " 

807 "codec" % (value, self.encoding), exc 

808 ) 

809 elif isinstance(value, OctetString): # a shortcut, bytes() would work the same way 

810 return value.asOctets() 

811 

812 elif isinstance(value, base.SimpleAsn1Type): # this mostly targets Integer objects 

813 return self.prettyIn(str(value)) 

814 

815 elif isinstance(value, (tuple, list)): 

816 return self.prettyIn(bytes(value)) 

817 

818 else: 

819 return bytes(value) 

820 

821 def __str__(self): 

822 try: 

823 return self._value.decode(self.encoding) 

824 

825 except UnicodeDecodeError as exc: 

826 raise error.PyAsn1UnicodeDecodeError( 

827 "Can't decode string '%s' with '%s' codec at " 

828 "'%s'" % (self._value, self.encoding, 

829 self.__class__.__name__), exc 

830 ) 

831 

832 def __bytes__(self): 

833 return bytes(self._value) 

834 

835 def asOctets(self): 

836 return bytes(self._value) 

837 

838 def asNumbers(self): 

839 return tuple(self._value) 

840 

841 # 

842 # Normally, `.prettyPrint()` is called from `__str__()`. Historically, 

843 # OctetString.prettyPrint() used to return hexified payload 

844 # representation in cases when non-printable content is present. At the 

845 # same time `str()` used to produce either octet-stream (Py2) or 

846 # text (Py3) representations. 

847 # 

848 # Therefore `OctetString.__str__()` -> `.prettyPrint()` call chain is 

849 # reversed to preserve the original behaviour. 

850 # 

851 # Eventually we should deprecate `.prettyPrint()` / `.prettyOut()` harness 

852 # and end up with just `__str__()` producing hexified representation while 

853 # both text and octet-stream representation should only be requested via 

854 # the `.asOctets()` method. 

855 # 

856 # Note: ASN.1 OCTET STRING is never mean to contain text! 

857 # 

858 

859 def prettyOut(self, value): 

860 return value 

861 

862 def prettyPrint(self, scope=0): 

863 # first see if subclass has its own .prettyOut() 

864 value = self.prettyOut(self._value) 

865 

866 if value is not self._value: 

867 return value 

868 

869 numbers = self.asNumbers() 

870 

871 for x in numbers: 

872 # hexify if needed 

873 if x < 32 or x > 126: 

874 return '0x' + ''.join(('%.2x' % x for x in numbers)) 

875 else: 

876 # this prevents infinite recursion 

877 return OctetString.__str__(self) 

878 

879 @staticmethod 

880 def fromBinaryString(value): 

881 """Create a |ASN.1| object initialized from a string of '0' and '1'. 

882 

883 Parameters 

884 ---------- 

885 value: :class:`str` 

886 Text string like '1010111' 

887 """ 

888 bitNo = 8 

889 byte = 0 

890 r = [] 

891 for v in value: 

892 if bitNo: 

893 bitNo -= 1 

894 else: 

895 bitNo = 7 

896 r.append(byte) 

897 byte = 0 

898 if v in ('0', '1'): 

899 v = int(v) 

900 else: 

901 raise error.PyAsn1Error( 

902 'Non-binary OCTET STRING initializer %s' % (v,) 

903 ) 

904 byte |= v << bitNo 

905 

906 r.append(byte) 

907 

908 return bytes(r) 

909 

910 @staticmethod 

911 def fromHexString(value): 

912 """Create a |ASN.1| object initialized from the hex string. 

913 

914 Parameters 

915 ---------- 

916 value: :class:`str` 

917 Text string like 'DEADBEEF' 

918 """ 

919 r = [] 

920 p = [] 

921 for v in value: 

922 if p: 

923 r.append(int(p + v, 16)) 

924 p = None 

925 else: 

926 p = v 

927 if p: 

928 r.append(int(p + '0', 16)) 

929 

930 return bytes(r) 

931 

932 # Immutable sequence object protocol 

933 

934 def __len__(self): 

935 return len(self._value) 

936 

937 def __getitem__(self, i): 

938 if i.__class__ is slice: 

939 return self.clone(self._value[i]) 

940 else: 

941 return self._value[i] 

942 

943 def __iter__(self): 

944 return iter(self._value) 

945 

946 def __contains__(self, value): 

947 return value in self._value 

948 

949 def __add__(self, value): 

950 return self.clone(self._value + self.prettyIn(value)) 

951 

952 def __radd__(self, value): 

953 return self.clone(self.prettyIn(value) + self._value) 

954 

955 def __mul__(self, value): 

956 return self.clone(self._value * value) 

957 

958 def __rmul__(self, value): 

959 return self * value 

960 

961 def __int__(self): 

962 return int(self._value) 

963 

964 def __float__(self): 

965 return float(self._value) 

966 

967 def __reversed__(self): 

968 return reversed(self._value) 

969 

970 

971class Null(OctetString): 

972 """Create |ASN.1| schema or value object. 

973 

974 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

975 objects are immutable and duck-type Python :class:`str` objects 

976 (always empty). 

977 

978 Keyword Args 

979 ------------ 

980 value: :class:`str` or |ASN.1| object 

981 Python empty :class:`str` literal or any object that evaluates to :obj:`False` 

982 If `value` is not given, schema object will be created. 

983 

984 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

985 Object representing non-default ASN.1 tag(s) 

986 

987 Raises 

988 ------ 

989 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

990 On constraint violation or bad initializer. 

991 

992 Examples 

993 -------- 

994 .. code-block:: python 

995 

996 class Ack(Null): 

997 ''' 

998 ASN.1 specification: 

999 

1000 Ack ::= NULL 

1001 ''' 

1002 ack = Ack('') 

1003 """ 

1004 

1005 #: Set (on class, not on instance) or return a 

1006 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

1007 #: associated with |ASN.1| type. 

1008 tagSet = tag.initTagSet( 

1009 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x05) 

1010 ) 

1011 subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(b'') 

1012 

1013 # Optimization for faster codec lookup 

1014 typeId = OctetString.getTypeId() 

1015 

1016 def prettyIn(self, value): 

1017 if value: 

1018 return value 

1019 

1020 return b'' 

1021 

1022 

1023class ObjectIdentifier(base.SimpleAsn1Type): 

1024 """Create |ASN.1| schema or value object. 

1025 

1026 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

1027 objects are immutable and duck-type Python :class:`tuple` objects 

1028 (tuple of non-negative integers). 

1029 

1030 Keyword Args 

1031 ------------ 

1032 value: :class:`tuple`, :class:`str` or |ASN.1| object 

1033 Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object. 

1034 If `value` is not given, schema object will be created. 

1035 

1036 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

1037 Object representing non-default ASN.1 tag(s) 

1038 

1039 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

1040 Object representing non-default ASN.1 subtype constraint(s). Constraints 

1041 verification for |ASN.1| type occurs automatically on object 

1042 instantiation. 

1043 

1044 Raises 

1045 ------ 

1046 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1047 On constraint violation or bad initializer. 

1048 

1049 Examples 

1050 -------- 

1051 .. code-block:: python 

1052 

1053 class ID(ObjectIdentifier): 

1054 ''' 

1055 ASN.1 specification: 

1056 

1057 ID ::= OBJECT IDENTIFIER 

1058 

1059 id-edims ID ::= { joint-iso-itu-t mhs-motif(6) edims(7) } 

1060 id-bp ID ::= { id-edims 11 } 

1061 ''' 

1062 id_edims = ID('2.6.7') 

1063 id_bp = id_edims + (11,) 

1064 """ 

1065 #: Set (on class, not on instance) or return a 

1066 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

1067 #: associated with |ASN.1| type. 

1068 tagSet = tag.initTagSet( 

1069 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x06) 

1070 ) 

1071 

1072 #: Set (on class, not on instance) or return a 

1073 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

1074 #: imposing constraints on |ASN.1| type initialization values. 

1075 subtypeSpec = constraint.ConstraintsIntersection() 

1076 

1077 # Optimization for faster codec lookup 

1078 typeId = base.SimpleAsn1Type.getTypeId() 

1079 

1080 def __add__(self, other): 

1081 return self.clone(self._value + other) 

1082 

1083 def __radd__(self, other): 

1084 return self.clone(other + self._value) 

1085 

1086 def asTuple(self): 

1087 return self._value 

1088 

1089 # Sequence object protocol 

1090 

1091 def __len__(self): 

1092 return len(self._value) 

1093 

1094 def __getitem__(self, i): 

1095 if i.__class__ is slice: 

1096 return self.clone(self._value[i]) 

1097 else: 

1098 return self._value[i] 

1099 

1100 def __iter__(self): 

1101 return iter(self._value) 

1102 

1103 def __contains__(self, value): 

1104 return value in self._value 

1105 

1106 def index(self, suboid): 

1107 return self._value.index(suboid) 

1108 

1109 def isPrefixOf(self, other): 

1110 """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object. 

1111 

1112 Parameters 

1113 ---------- 

1114 other: |ASN.1| object 

1115 |ASN.1| object 

1116 

1117 Returns 

1118 ------- 

1119 : :class:`bool` 

1120 :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object 

1121 or :obj:`False` otherwise. 

1122 """ 

1123 l = len(self) 

1124 if l <= len(other): 

1125 if self._value[:l] == other[:l]: 

1126 return True 

1127 return False 

1128 

1129 def prettyIn(self, value): 

1130 if isinstance(value, ObjectIdentifier): 

1131 return tuple(value) 

1132 elif isinstance(value, str): 

1133 if '-' in value: 

1134 raise error.PyAsn1Error( 

1135 # sys.exc_info in case prettyIn was called while handling an exception 

1136 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) 

1137 ) 

1138 try: 

1139 return tuple([int(subOid) for subOid in value.split('.') if subOid]) 

1140 except ValueError as exc: 

1141 raise error.PyAsn1Error( 

1142 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, exc) 

1143 ) 

1144 

1145 try: 

1146 tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0]) 

1147 

1148 except (ValueError, TypeError) as exc: 

1149 raise error.PyAsn1Error( 

1150 'Malformed Object ID %s at %s: %s' % (value, self.__class__.__name__, exc) 

1151 ) 

1152 

1153 if len(tupleOfInts) == len(value): 

1154 return tupleOfInts 

1155 

1156 raise error.PyAsn1Error('Malformed Object ID %s at %s' % (value, self.__class__.__name__)) 

1157 

1158 def prettyOut(self, value): 

1159 return '.'.join([str(x) for x in value]) 

1160 

1161 

1162class RelativeOID(base.SimpleAsn1Type): 

1163 """Create |ASN.1| schema or value object. 

1164 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

1165 objects are immutable and duck-type Python :class:`tuple` objects 

1166 (tuple of non-negative integers). 

1167 Keyword Args 

1168 ------------ 

1169 value: :class:`tuple`, :class:`str` or |ASN.1| object 

1170 Python sequence of :class:`int` or :class:`str` literal or |ASN.1| object. 

1171 If `value` is not given, schema object will be created. 

1172 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

1173 Object representing non-default ASN.1 tag(s) 

1174 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

1175 Object representing non-default ASN.1 subtype constraint(s). Constraints 

1176 verification for |ASN.1| type occurs automatically on object 

1177 instantiation. 

1178 Raises 

1179 ------ 

1180 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1181 On constraint violation or bad initializer. 

1182 Examples 

1183 -------- 

1184 .. code-block:: python 

1185 class RelOID(RelativeOID): 

1186 ''' 

1187 ASN.1 specification: 

1188 id-pad-null RELATIVE-OID ::= { 0 } 

1189 id-pad-once RELATIVE-OID ::= { 5 6 } 

1190 id-pad-twice RELATIVE-OID ::= { 5 6 7 } 

1191 ''' 

1192 id_pad_null = RelOID('0') 

1193 id_pad_once = RelOID('5.6') 

1194 id_pad_twice = id_pad_once + (7,) 

1195 """ 

1196 #: Set (on class, not on instance) or return a 

1197 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

1198 #: associated with |ASN.1| type. 

1199 tagSet = tag.initTagSet( 

1200 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0d) 

1201 ) 

1202 

1203 #: Set (on class, not on instance) or return a 

1204 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

1205 #: imposing constraints on |ASN.1| type initialization values. 

1206 subtypeSpec = constraint.ConstraintsIntersection() 

1207 

1208 # Optimization for faster codec lookup 

1209 typeId = base.SimpleAsn1Type.getTypeId() 

1210 

1211 def __add__(self, other): 

1212 return self.clone(self._value + other) 

1213 

1214 def __radd__(self, other): 

1215 return self.clone(other + self._value) 

1216 

1217 def asTuple(self): 

1218 return self._value 

1219 

1220 # Sequence object protocol 

1221 

1222 def __len__(self): 

1223 return len(self._value) 

1224 

1225 def __getitem__(self, i): 

1226 if i.__class__ is slice: 

1227 return self.clone(self._value[i]) 

1228 else: 

1229 return self._value[i] 

1230 

1231 def __iter__(self): 

1232 return iter(self._value) 

1233 

1234 def __contains__(self, value): 

1235 return value in self._value 

1236 

1237 def index(self, suboid): 

1238 return self._value.index(suboid) 

1239 

1240 def isPrefixOf(self, other): 

1241 """Indicate if this |ASN.1| object is a prefix of other |ASN.1| object. 

1242 Parameters 

1243 ---------- 

1244 other: |ASN.1| object 

1245 |ASN.1| object 

1246 Returns 

1247 ------- 

1248 : :class:`bool` 

1249 :obj:`True` if this |ASN.1| object is a parent (e.g. prefix) of the other |ASN.1| object 

1250 or :obj:`False` otherwise. 

1251 """ 

1252 l = len(self) 

1253 if l <= len(other): 

1254 if self._value[:l] == other[:l]: 

1255 return True 

1256 return False 

1257 

1258 def prettyIn(self, value): 

1259 if isinstance(value, RelativeOID): 

1260 return tuple(value) 

1261 elif isinstance(value, str): 

1262 if '-' in value: 

1263 raise error.PyAsn1Error( 

1264 # sys.exc_info in case prettyIn was called while handling an exception 

1265 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, sys.exc_info()[1]) 

1266 ) 

1267 try: 

1268 return tuple([int(subOid) for subOid in value.split('.') if subOid]) 

1269 except ValueError as exc: 

1270 raise error.PyAsn1Error( 

1271 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, exc) 

1272 ) 

1273 

1274 try: 

1275 tupleOfInts = tuple([int(subOid) for subOid in value if subOid >= 0]) 

1276 

1277 except (ValueError, TypeError) as exc: 

1278 raise error.PyAsn1Error( 

1279 'Malformed RELATIVE-OID %s at %s: %s' % (value, self.__class__.__name__, exc) 

1280 ) 

1281 

1282 if len(tupleOfInts) == len(value): 

1283 return tupleOfInts 

1284 

1285 raise error.PyAsn1Error('Malformed RELATIVE-OID %s at %s' % (value, self.__class__.__name__)) 

1286 

1287 def prettyOut(self, value): 

1288 return '.'.join([str(x) for x in value]) 

1289 

1290 

1291class Real(base.SimpleAsn1Type): 

1292 """Create |ASN.1| schema or value object. 

1293 

1294 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

1295 objects are immutable and duck-type Python :class:`float` objects. 

1296 Additionally, |ASN.1| objects behave like a :class:`tuple` in which case its 

1297 elements are mantissa, base and exponent. 

1298 

1299 Keyword Args 

1300 ------------ 

1301 value: :class:`tuple`, :class:`float` or |ASN.1| object 

1302 Python sequence of :class:`int` (representing mantissa, base and 

1303 exponent) or :class:`float` instance or |ASN.1| object. 

1304 If `value` is not given, schema object will be created. 

1305 

1306 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

1307 Object representing non-default ASN.1 tag(s) 

1308 

1309 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

1310 Object representing non-default ASN.1 subtype constraint(s). Constraints 

1311 verification for |ASN.1| type occurs automatically on object 

1312 instantiation. 

1313 

1314 Raises 

1315 ------ 

1316 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1317 On constraint violation or bad initializer. 

1318 

1319 Examples 

1320 -------- 

1321 .. code-block:: python 

1322 

1323 class Pi(Real): 

1324 ''' 

1325 ASN.1 specification: 

1326 

1327 Pi ::= REAL 

1328 

1329 pi Pi ::= { mantissa 314159, base 10, exponent -5 } 

1330 

1331 ''' 

1332 pi = Pi((314159, 10, -5)) 

1333 """ 

1334 binEncBase = None # binEncBase = 16 is recommended for large numbers 

1335 

1336 try: 

1337 _plusInf = float('inf') 

1338 _minusInf = float('-inf') 

1339 _inf = _plusInf, _minusInf 

1340 

1341 except ValueError: 

1342 # Infinity support is platform and Python dependent 

1343 _plusInf = _minusInf = None 

1344 _inf = () 

1345 

1346 #: Set (on class, not on instance) or return a 

1347 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

1348 #: associated with |ASN.1| type. 

1349 tagSet = tag.initTagSet( 

1350 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x09) 

1351 ) 

1352 

1353 #: Set (on class, not on instance) or return a 

1354 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

1355 #: imposing constraints on |ASN.1| type initialization values. 

1356 subtypeSpec = constraint.ConstraintsIntersection() 

1357 

1358 # Optimization for faster codec lookup 

1359 typeId = base.SimpleAsn1Type.getTypeId() 

1360 

1361 @staticmethod 

1362 def __normalizeBase10(value): 

1363 m, b, e = value 

1364 while m and m % 10 == 0: 

1365 m /= 10 

1366 e += 1 

1367 return m, b, e 

1368 

1369 def prettyIn(self, value): 

1370 if isinstance(value, tuple) and len(value) == 3: 

1371 if (not isinstance(value[0], (int, float)) or 

1372 not isinstance(value[1], int) or 

1373 not isinstance(value[2], int)): 

1374 raise error.PyAsn1Error('Lame Real value syntax: %s' % (value,)) 

1375 if (isinstance(value[0], float) and 

1376 self._inf and value[0] in self._inf): 

1377 return value[0] 

1378 if value[1] not in (2, 10): 

1379 raise error.PyAsn1Error( 

1380 'Prohibited base for Real value: %s' % (value[1],) 

1381 ) 

1382 if value[1] == 10: 

1383 value = self.__normalizeBase10(value) 

1384 return value 

1385 elif isinstance(value, int): 

1386 return self.__normalizeBase10((value, 10, 0)) 

1387 elif isinstance(value, float) or isinstance(value, str): 

1388 if isinstance(value, str): 

1389 try: 

1390 value = float(value) 

1391 except ValueError: 

1392 raise error.PyAsn1Error( 

1393 'Bad real value syntax: %s' % (value,) 

1394 ) 

1395 if self._inf and value in self._inf: 

1396 return value 

1397 else: 

1398 e = 0 

1399 while int(value) != value: 

1400 value *= 10 

1401 e -= 1 

1402 return self.__normalizeBase10((int(value), 10, e)) 

1403 elif isinstance(value, Real): 

1404 return tuple(value) 

1405 raise error.PyAsn1Error( 

1406 'Bad real value syntax: %s' % (value,) 

1407 ) 

1408 

1409 def prettyPrint(self, scope=0): 

1410 try: 

1411 return self.prettyOut(float(self)) 

1412 

1413 except OverflowError: 

1414 return '<overflow>' 

1415 

1416 @property 

1417 def isPlusInf(self): 

1418 """Indicate PLUS-INFINITY object value 

1419 

1420 Returns 

1421 ------- 

1422 : :class:`bool` 

1423 :obj:`True` if calling object represents plus infinity 

1424 or :obj:`False` otherwise. 

1425 

1426 """ 

1427 return self._value == self._plusInf 

1428 

1429 @property 

1430 def isMinusInf(self): 

1431 """Indicate MINUS-INFINITY object value 

1432 

1433 Returns 

1434 ------- 

1435 : :class:`bool` 

1436 :obj:`True` if calling object represents minus infinity 

1437 or :obj:`False` otherwise. 

1438 """ 

1439 return self._value == self._minusInf 

1440 

1441 @property 

1442 def isInf(self): 

1443 return self._value in self._inf 

1444 

1445 def __add__(self, value): 

1446 return self.clone(float(self) + value) 

1447 

1448 def __radd__(self, value): 

1449 return self + value 

1450 

1451 def __mul__(self, value): 

1452 return self.clone(float(self) * value) 

1453 

1454 def __rmul__(self, value): 

1455 return self * value 

1456 

1457 def __sub__(self, value): 

1458 return self.clone(float(self) - value) 

1459 

1460 def __rsub__(self, value): 

1461 return self.clone(value - float(self)) 

1462 

1463 def __mod__(self, value): 

1464 return self.clone(float(self) % value) 

1465 

1466 def __rmod__(self, value): 

1467 return self.clone(value % float(self)) 

1468 

1469 def __pow__(self, value, modulo=None): 

1470 return self.clone(pow(float(self), value, modulo)) 

1471 

1472 def __rpow__(self, value): 

1473 return self.clone(pow(value, float(self))) 

1474 

1475 def __truediv__(self, value): 

1476 return self.clone(float(self) / value) 

1477 

1478 def __rtruediv__(self, value): 

1479 return self.clone(value / float(self)) 

1480 

1481 def __divmod__(self, value): 

1482 return self.clone(float(self) // value) 

1483 

1484 def __rdivmod__(self, value): 

1485 return self.clone(value // float(self)) 

1486 

1487 def __int__(self): 

1488 return int(float(self)) 

1489 

1490 def __float__(self): 

1491 if self._value in self._inf: 

1492 return self._value 

1493 else: 

1494 return float( 

1495 self._value[0] * pow(self._value[1], self._value[2]) 

1496 ) 

1497 

1498 def __abs__(self): 

1499 return self.clone(abs(float(self))) 

1500 

1501 def __pos__(self): 

1502 return self.clone(+float(self)) 

1503 

1504 def __neg__(self): 

1505 return self.clone(-float(self)) 

1506 

1507 def __round__(self, n=0): 

1508 r = round(float(self), n) 

1509 if n: 

1510 return self.clone(r) 

1511 else: 

1512 return r 

1513 

1514 def __floor__(self): 

1515 return self.clone(math.floor(float(self))) 

1516 

1517 def __ceil__(self): 

1518 return self.clone(math.ceil(float(self))) 

1519 

1520 def __trunc__(self): 

1521 return self.clone(math.trunc(float(self))) 

1522 

1523 def __lt__(self, value): 

1524 return float(self) < value 

1525 

1526 def __le__(self, value): 

1527 return float(self) <= value 

1528 

1529 def __eq__(self, value): 

1530 return float(self) == value 

1531 

1532 def __ne__(self, value): 

1533 return float(self) != value 

1534 

1535 def __gt__(self, value): 

1536 return float(self) > value 

1537 

1538 def __ge__(self, value): 

1539 return float(self) >= value 

1540 

1541 def __bool__(self): 

1542 return bool(float(self)) 

1543 

1544 __hash__ = base.SimpleAsn1Type.__hash__ 

1545 

1546 def __getitem__(self, idx): 

1547 if self._value in self._inf: 

1548 raise error.PyAsn1Error('Invalid infinite value operation') 

1549 else: 

1550 return self._value[idx] 

1551 

1552 # compatibility stubs 

1553 

1554 def isPlusInfinity(self): 

1555 return self.isPlusInf 

1556 

1557 def isMinusInfinity(self): 

1558 return self.isMinusInf 

1559 

1560 def isInfinity(self): 

1561 return self.isInf 

1562 

1563 

1564class Enumerated(Integer): 

1565 """Create |ASN.1| schema or value object. 

1566 

1567 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, its 

1568 objects are immutable and duck-type Python :class:`int` objects. 

1569 

1570 Keyword Args 

1571 ------------ 

1572 value: :class:`int`, :class:`str` or |ASN.1| object 

1573 Python :class:`int` or :class:`str` literal or |ASN.1| object. 

1574 If `value` is not given, schema object will be created. 

1575 

1576 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

1577 Object representing non-default ASN.1 tag(s) 

1578 

1579 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

1580 Object representing non-default ASN.1 subtype constraint(s). Constraints 

1581 verification for |ASN.1| type occurs automatically on object 

1582 instantiation. 

1583 

1584 namedValues: :py:class:`~pyasn1.type.namedval.NamedValues` 

1585 Object representing non-default symbolic aliases for numbers 

1586 

1587 Raises 

1588 ------ 

1589 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1590 On constraint violation or bad initializer. 

1591 

1592 Examples 

1593 -------- 

1594 

1595 .. code-block:: python 

1596 

1597 class RadioButton(Enumerated): 

1598 ''' 

1599 ASN.1 specification: 

1600 

1601 RadioButton ::= ENUMERATED { button1(0), button2(1), 

1602 button3(2) } 

1603 

1604 selected-by-default RadioButton ::= button1 

1605 ''' 

1606 namedValues = NamedValues( 

1607 ('button1', 0), ('button2', 1), 

1608 ('button3', 2) 

1609 ) 

1610 

1611 selected_by_default = RadioButton('button1') 

1612 """ 

1613 #: Set (on class, not on instance) or return a 

1614 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

1615 #: associated with |ASN.1| type. 

1616 tagSet = tag.initTagSet( 

1617 tag.Tag(tag.tagClassUniversal, tag.tagFormatSimple, 0x0A) 

1618 ) 

1619 

1620 #: Set (on class, not on instance) or return a 

1621 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

1622 #: imposing constraints on |ASN.1| type initialization values. 

1623 subtypeSpec = constraint.ConstraintsIntersection() 

1624 

1625 # Optimization for faster codec lookup 

1626 typeId = Integer.getTypeId() 

1627 

1628 #: Default :py:class:`~pyasn1.type.namedval.NamedValues` object 

1629 #: representing symbolic aliases for numbers 

1630 namedValues = namedval.NamedValues() 

1631 

1632 

1633# "Structured" ASN.1 types 

1634 

1635class SequenceOfAndSetOfBase(base.ConstructedAsn1Type): 

1636 """Create |ASN.1| schema or value object. 

1637 

1638 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, 

1639 its objects are mutable and duck-type Python :class:`list` objects. 

1640 

1641 Keyword Args 

1642 ------------ 

1643 componentType : :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

1644 A pyasn1 object representing ASN.1 type allowed within |ASN.1| type 

1645 

1646 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

1647 Object representing non-default ASN.1 tag(s) 

1648 

1649 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

1650 Object representing non-default ASN.1 subtype constraint(s). Constraints 

1651 verification for |ASN.1| type can only occur on explicit 

1652 `.isInconsistent` call. 

1653 

1654 Examples 

1655 -------- 

1656 

1657 .. code-block:: python 

1658 

1659 class LotteryDraw(SequenceOf): # SetOf is similar 

1660 ''' 

1661 ASN.1 specification: 

1662 

1663 LotteryDraw ::= SEQUENCE OF INTEGER 

1664 ''' 

1665 componentType = Integer() 

1666 

1667 lotteryDraw = LotteryDraw() 

1668 lotteryDraw.extend([123, 456, 789]) 

1669 """ 

1670 def __init__(self, *args, **kwargs): 

1671 # support positional params for backward compatibility 

1672 if args: 

1673 for key, value in zip(('componentType', 'tagSet', 

1674 'subtypeSpec'), args): 

1675 if key in kwargs: 

1676 raise error.PyAsn1Error('Conflicting positional and keyword params!') 

1677 kwargs['componentType'] = value 

1678 

1679 self._componentValues = noValue 

1680 

1681 base.ConstructedAsn1Type.__init__(self, **kwargs) 

1682 

1683 # Python list protocol 

1684 

1685 def __getitem__(self, idx): 

1686 try: 

1687 return self.getComponentByPosition(idx) 

1688 

1689 except error.PyAsn1Error as exc: 

1690 raise IndexError(exc) 

1691 

1692 def __setitem__(self, idx, value): 

1693 try: 

1694 self.setComponentByPosition(idx, value) 

1695 

1696 except error.PyAsn1Error as exc: 

1697 raise IndexError(exc) 

1698 

1699 def append(self, value): 

1700 if self._componentValues is noValue: 

1701 pos = 0 

1702 

1703 else: 

1704 pos = len(self._componentValues) 

1705 

1706 self[pos] = value 

1707 

1708 def count(self, value): 

1709 return list(self._componentValues.values()).count(value) 

1710 

1711 def extend(self, values): 

1712 for value in values: 

1713 self.append(value) 

1714 

1715 if self._componentValues is noValue: 

1716 self._componentValues = {} 

1717 

1718 def index(self, value, start=0, stop=None): 

1719 if stop is None: 

1720 stop = len(self) 

1721 

1722 indices, values = zip(*self._componentValues.items()) 

1723 

1724 # TODO: remove when Py2.5 support is gone 

1725 values = list(values) 

1726 

1727 try: 

1728 return indices[values.index(value, start, stop)] 

1729 

1730 except error.PyAsn1Error as exc: 

1731 raise ValueError(exc) 

1732 

1733 def reverse(self): 

1734 self._componentValues.reverse() 

1735 

1736 def sort(self, key=None, reverse=False): 

1737 self._componentValues = dict( 

1738 enumerate(sorted(self._componentValues.values(), 

1739 key=key, reverse=reverse))) 

1740 

1741 def __len__(self): 

1742 if self._componentValues is noValue or not self._componentValues: 

1743 return 0 

1744 

1745 return max(self._componentValues) + 1 

1746 

1747 def __iter__(self): 

1748 for idx in range(0, len(self)): 

1749 yield self.getComponentByPosition(idx) 

1750 

1751 def _cloneComponentValues(self, myClone, cloneValueFlag): 

1752 for idx, componentValue in self._componentValues.items(): 

1753 if componentValue is not noValue: 

1754 if isinstance(componentValue, base.ConstructedAsn1Type): 

1755 myClone.setComponentByPosition( 

1756 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

1757 ) 

1758 else: 

1759 myClone.setComponentByPosition(idx, componentValue.clone()) 

1760 

1761 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 

1762 """Return |ASN.1| type component value by position. 

1763 

1764 Equivalent to Python sequence subscription operation (e.g. `[]`). 

1765 

1766 Parameters 

1767 ---------- 

1768 idx : :class:`int` 

1769 Component index (zero-based). Must either refer to an existing 

1770 component or to N+1 component (if *componentType* is set). In the latter 

1771 case a new component type gets instantiated and appended to the |ASN.1| 

1772 sequence. 

1773 

1774 Keyword Args 

1775 ------------ 

1776 default: :class:`object` 

1777 If set and requested component is a schema object, return the `default` 

1778 object instead of the requested component. 

1779 

1780 instantiate: :class:`bool` 

1781 If :obj:`True` (default), inner component will be automatically instantiated. 

1782 If :obj:`False` either existing component or the :class:`NoValue` object will be 

1783 returned. 

1784 

1785 Returns 

1786 ------- 

1787 : :py:class:`~pyasn1.type.base.PyAsn1Item` 

1788 Instantiate |ASN.1| component type or return existing component value 

1789 

1790 Examples 

1791 -------- 

1792 

1793 .. code-block:: python 

1794 

1795 # can also be SetOf 

1796 class MySequenceOf(SequenceOf): 

1797 componentType = OctetString() 

1798 

1799 s = MySequenceOf() 

1800 

1801 # returns component #0 with `.isValue` property False 

1802 s.getComponentByPosition(0) 

1803 

1804 # returns None 

1805 s.getComponentByPosition(0, default=None) 

1806 

1807 s.clear() 

1808 

1809 # returns noValue 

1810 s.getComponentByPosition(0, instantiate=False) 

1811 

1812 # sets component #0 to OctetString() ASN.1 schema 

1813 # object and returns it 

1814 s.getComponentByPosition(0, instantiate=True) 

1815 

1816 # sets component #0 to ASN.1 value object 

1817 s.setComponentByPosition(0, 'ABCD') 

1818 

1819 # returns OctetString('ABCD') value object 

1820 s.getComponentByPosition(0, instantiate=False) 

1821 

1822 s.clear() 

1823 

1824 # returns noValue 

1825 s.getComponentByPosition(0, instantiate=False) 

1826 """ 

1827 if isinstance(idx, slice): 

1828 indices = tuple(range(len(self))) 

1829 return [self.getComponentByPosition(subidx, default, instantiate) 

1830 for subidx in indices[idx]] 

1831 

1832 if idx < 0: 

1833 idx = len(self) + idx 

1834 if idx < 0: 

1835 raise error.PyAsn1Error( 

1836 'SequenceOf/SetOf index is out of range') 

1837 

1838 try: 

1839 componentValue = self._componentValues[idx] 

1840 

1841 except (KeyError, error.PyAsn1Error): 

1842 if not instantiate: 

1843 return default 

1844 

1845 self.setComponentByPosition(idx) 

1846 

1847 componentValue = self._componentValues[idx] 

1848 

1849 if default is noValue or componentValue.isValue: 

1850 return componentValue 

1851 else: 

1852 return default 

1853 

1854 def setComponentByPosition(self, idx, value=noValue, 

1855 verifyConstraints=True, 

1856 matchTags=True, 

1857 matchConstraints=True): 

1858 """Assign |ASN.1| type component by position. 

1859 

1860 Equivalent to Python sequence item assignment operation (e.g. `[]`) 

1861 or list.append() (when idx == len(self)). 

1862 

1863 Parameters 

1864 ---------- 

1865 idx: :class:`int` 

1866 Component index (zero-based). Must either refer to existing 

1867 component or to N+1 component. In the latter case a new component 

1868 type gets instantiated (if *componentType* is set, or given ASN.1 

1869 object is taken otherwise) and appended to the |ASN.1| sequence. 

1870 

1871 Keyword Args 

1872 ------------ 

1873 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

1874 A Python value to initialize |ASN.1| component with (if *componentType* is set) 

1875 or ASN.1 value object to assign to |ASN.1| component. 

1876 If `value` is not given, schema object will be set as a component. 

1877 

1878 verifyConstraints: :class:`bool` 

1879 If :obj:`False`, skip constraints validation 

1880 

1881 matchTags: :class:`bool` 

1882 If :obj:`False`, skip component tags matching 

1883 

1884 matchConstraints: :class:`bool` 

1885 If :obj:`False`, skip component constraints matching 

1886 

1887 Returns 

1888 ------- 

1889 self 

1890 

1891 Raises 

1892 ------ 

1893 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1894 On constraint violation or bad initializer 

1895 IndexError 

1896 When idx > len(self) 

1897 """ 

1898 if isinstance(idx, slice): 

1899 indices = tuple(range(len(self))) 

1900 startIdx = indices and indices[idx][0] or 0 

1901 for subIdx, subValue in enumerate(value): 

1902 self.setComponentByPosition( 

1903 startIdx + subIdx, subValue, verifyConstraints, 

1904 matchTags, matchConstraints) 

1905 return self 

1906 

1907 if idx < 0: 

1908 idx = len(self) + idx 

1909 if idx < 0: 

1910 raise error.PyAsn1Error( 

1911 'SequenceOf/SetOf index is out of range') 

1912 

1913 componentType = self.componentType 

1914 

1915 if self._componentValues is noValue: 

1916 componentValues = {} 

1917 

1918 else: 

1919 componentValues = self._componentValues 

1920 

1921 currentValue = componentValues.get(idx, noValue) 

1922 

1923 if value is noValue: 

1924 if componentType is not None: 

1925 value = componentType.clone() 

1926 

1927 elif currentValue is noValue: 

1928 raise error.PyAsn1Error('Component type not defined') 

1929 

1930 elif not isinstance(value, base.Asn1Item): 

1931 if (componentType is not None and 

1932 isinstance(componentType, base.SimpleAsn1Type)): 

1933 value = componentType.clone(value=value) 

1934 

1935 elif (currentValue is not noValue and 

1936 isinstance(currentValue, base.SimpleAsn1Type)): 

1937 value = currentValue.clone(value=value) 

1938 

1939 else: 

1940 raise error.PyAsn1Error( 

1941 'Non-ASN.1 value %r and undefined component' 

1942 ' type at %r' % (value, self)) 

1943 

1944 elif componentType is not None and (matchTags or matchConstraints): 

1945 subtypeChecker = ( 

1946 self.strictConstraints and 

1947 componentType.isSameTypeWith or 

1948 componentType.isSuperTypeOf) 

1949 

1950 if not subtypeChecker(value, verifyConstraints and matchTags, 

1951 verifyConstraints and matchConstraints): 

1952 # TODO: we should wrap componentType with UnnamedType to carry 

1953 # additional properties associated with componentType 

1954 if componentType.typeId != Any.typeId: 

1955 raise error.PyAsn1Error( 

1956 'Component value is tag-incompatible: %r vs ' 

1957 '%r' % (value, componentType)) 

1958 

1959 componentValues[idx] = value 

1960 

1961 self._componentValues = componentValues 

1962 

1963 return self 

1964 

1965 @property 

1966 def componentTagMap(self): 

1967 if self.componentType is not None: 

1968 return self.componentType.tagMap 

1969 

1970 @property 

1971 def components(self): 

1972 return [self._componentValues[idx] 

1973 for idx in sorted(self._componentValues)] 

1974 

1975 def clear(self): 

1976 """Remove all components and become an empty |ASN.1| value object. 

1977 

1978 Has the same effect on |ASN.1| object as it does on :class:`list` 

1979 built-in. 

1980 """ 

1981 self._componentValues = {} 

1982 return self 

1983 

1984 def reset(self): 

1985 """Remove all components and become a |ASN.1| schema object. 

1986 

1987 See :meth:`isValue` property for more information on the 

1988 distinction between value and schema objects. 

1989 """ 

1990 self._componentValues = noValue 

1991 return self 

1992 

1993 def prettyPrint(self, scope=0): 

1994 scope += 1 

1995 representation = self.__class__.__name__ + ':\n' 

1996 

1997 if not self.isValue: 

1998 return representation 

1999 

2000 for idx, componentValue in enumerate(self): 

2001 representation += ' ' * scope 

2002 if (componentValue is noValue and 

2003 self.componentType is not None): 

2004 representation += '<empty>' 

2005 else: 

2006 representation += componentValue.prettyPrint(scope) 

2007 

2008 return representation 

2009 

2010 def prettyPrintType(self, scope=0): 

2011 scope += 1 

2012 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) 

2013 if self.componentType is not None: 

2014 representation += ' ' * scope 

2015 representation += self.componentType.prettyPrintType(scope) 

2016 return representation + '\n' + ' ' * (scope - 1) + '}' 

2017 

2018 

2019 @property 

2020 def isValue(self): 

2021 """Indicate that |ASN.1| object represents ASN.1 value. 

2022 

2023 If *isValue* is :obj:`False` then this object represents just ASN.1 schema. 

2024 

2025 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, 

2026 this object can also be used like a Python built-in object 

2027 (e.g. :class:`int`, :class:`str`, :class:`dict` etc.). 

2028 

2029 Returns 

2030 ------- 

2031 : :class:`bool` 

2032 :obj:`False` if object represents just ASN.1 schema. 

2033 :obj:`True` if object represents ASN.1 schema and can be used as a normal value. 

2034 

2035 Note 

2036 ---- 

2037 There is an important distinction between PyASN1 schema and value objects. 

2038 The PyASN1 schema objects can only participate in ASN.1 schema-related 

2039 operations (e.g. defining or testing the structure of the data). Most 

2040 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 

2041 encoding/decoding serialised ASN.1 contents. 

2042 

2043 The PyASN1 value objects can **additionally** participate in many operations 

2044 involving regular Python objects (e.g. arithmetic, comprehension etc). 

2045 """ 

2046 if self._componentValues is noValue: 

2047 return False 

2048 

2049 if len(self._componentValues) != len(self): 

2050 return False 

2051 

2052 for componentValue in self._componentValues.values(): 

2053 if componentValue is noValue or not componentValue.isValue: 

2054 return False 

2055 

2056 return True 

2057 

2058 @property 

2059 def isInconsistent(self): 

2060 """Run necessary checks to ensure |ASN.1| object consistency. 

2061 

2062 Default action is to verify |ASN.1| object against constraints imposed 

2063 by `subtypeSpec`. 

2064 

2065 Raises 

2066 ------ 

2067 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found 

2068 """ 

2069 if self.componentType is noValue or not self.subtypeSpec: 

2070 return False 

2071 

2072 if self._componentValues is noValue: 

2073 return True 

2074 

2075 mapping = {} 

2076 

2077 for idx, value in self._componentValues.items(): 

2078 # Absent fields are not in the mapping 

2079 if value is noValue: 

2080 continue 

2081 

2082 mapping[idx] = value 

2083 

2084 try: 

2085 # Represent SequenceOf/SetOf as a bare dict to constraints chain 

2086 self.subtypeSpec(mapping) 

2087 

2088 except error.PyAsn1Error as exc: 

2089 return exc 

2090 

2091 return False 

2092 

2093class SequenceOf(SequenceOfAndSetOfBase): 

2094 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2095 

2096 #: Set (on class, not on instance) or return a 

2097 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

2098 #: associated with |ASN.1| type. 

2099 tagSet = tag.initTagSet( 

2100 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) 

2101 ) 

2102 

2103 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

2104 #: object representing ASN.1 type allowed within |ASN.1| type 

2105 componentType = None 

2106 

2107 #: Set (on class, not on instance) or return a 

2108 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

2109 #: imposing constraints on |ASN.1| type initialization values. 

2110 subtypeSpec = constraint.ConstraintsIntersection() 

2111 

2112 # Disambiguation ASN.1 types identification 

2113 typeId = SequenceOfAndSetOfBase.getTypeId() 

2114 

2115 

2116class SetOf(SequenceOfAndSetOfBase): 

2117 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2118 

2119 #: Set (on class, not on instance) or return a 

2120 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

2121 #: associated with |ASN.1| type. 

2122 tagSet = tag.initTagSet( 

2123 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) 

2124 ) 

2125 

2126 #: Default :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

2127 #: object representing ASN.1 type allowed within |ASN.1| type 

2128 componentType = None 

2129 

2130 #: Set (on class, not on instance) or return a 

2131 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

2132 #: imposing constraints on |ASN.1| type initialization values. 

2133 subtypeSpec = constraint.ConstraintsIntersection() 

2134 

2135 # Disambiguation ASN.1 types identification 

2136 typeId = SequenceOfAndSetOfBase.getTypeId() 

2137 

2138 

2139class SequenceAndSetBase(base.ConstructedAsn1Type): 

2140 """Create |ASN.1| schema or value object. 

2141 

2142 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, 

2143 its objects are mutable and duck-type Python :class:`dict` objects. 

2144 

2145 Keyword Args 

2146 ------------ 

2147 componentType: :py:class:`~pyasn1.type.namedtype.NamedType` 

2148 Object holding named ASN.1 types allowed within this collection 

2149 

2150 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

2151 Object representing non-default ASN.1 tag(s) 

2152 

2153 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

2154 Object representing non-default ASN.1 subtype constraint(s). Constraints 

2155 verification for |ASN.1| type can only occur on explicit 

2156 `.isInconsistent` call. 

2157 

2158 Examples 

2159 -------- 

2160 

2161 .. code-block:: python 

2162 

2163 class Description(Sequence): # Set is similar 

2164 ''' 

2165 ASN.1 specification: 

2166 

2167 Description ::= SEQUENCE { 

2168 surname IA5String, 

2169 first-name IA5String OPTIONAL, 

2170 age INTEGER DEFAULT 40 

2171 } 

2172 ''' 

2173 componentType = NamedTypes( 

2174 NamedType('surname', IA5String()), 

2175 OptionalNamedType('first-name', IA5String()), 

2176 DefaultedNamedType('age', Integer(40)) 

2177 ) 

2178 

2179 descr = Description() 

2180 descr['surname'] = 'Smith' 

2181 descr['first-name'] = 'John' 

2182 """ 

2183 #: Default :py:class:`~pyasn1.type.namedtype.NamedTypes` 

2184 #: object representing named ASN.1 types allowed within |ASN.1| type 

2185 componentType = namedtype.NamedTypes() 

2186 

2187 

2188 class DynamicNames(object): 

2189 """Fields names/positions mapping for component-less objects""" 

2190 def __init__(self): 

2191 self._keyToIdxMap = {} 

2192 self._idxToKeyMap = {} 

2193 

2194 def __len__(self): 

2195 return len(self._keyToIdxMap) 

2196 

2197 def __contains__(self, item): 

2198 return item in self._keyToIdxMap or item in self._idxToKeyMap 

2199 

2200 def __iter__(self): 

2201 return (self._idxToKeyMap[idx] for idx in range(len(self._idxToKeyMap))) 

2202 

2203 def __getitem__(self, item): 

2204 try: 

2205 return self._keyToIdxMap[item] 

2206 

2207 except KeyError: 

2208 return self._idxToKeyMap[item] 

2209 

2210 def getNameByPosition(self, idx): 

2211 try: 

2212 return self._idxToKeyMap[idx] 

2213 

2214 except KeyError: 

2215 raise error.PyAsn1Error('Type position out of range') 

2216 

2217 def getPositionByName(self, name): 

2218 try: 

2219 return self._keyToIdxMap[name] 

2220 

2221 except KeyError: 

2222 raise error.PyAsn1Error('Name %s not found' % (name,)) 

2223 

2224 def addField(self, idx): 

2225 self._keyToIdxMap['field-%d' % idx] = idx 

2226 self._idxToKeyMap[idx] = 'field-%d' % idx 

2227 

2228 

2229 def __init__(self, **kwargs): 

2230 base.ConstructedAsn1Type.__init__(self, **kwargs) 

2231 self._componentTypeLen = len(self.componentType) 

2232 if self._componentTypeLen: 

2233 self._componentValues = [] 

2234 else: 

2235 self._componentValues = noValue 

2236 self._dynamicNames = self._componentTypeLen or self.DynamicNames() 

2237 

2238 def __getitem__(self, idx): 

2239 if isinstance(idx, str): 

2240 try: 

2241 return self.getComponentByName(idx) 

2242 

2243 except error.PyAsn1Error as exc: 

2244 # duck-typing dict 

2245 raise KeyError(exc) 

2246 

2247 else: 

2248 try: 

2249 return self.getComponentByPosition(idx) 

2250 

2251 except error.PyAsn1Error as exc: 

2252 # duck-typing list 

2253 raise IndexError(exc) 

2254 

2255 def __setitem__(self, idx, value): 

2256 if isinstance(idx, str): 

2257 try: 

2258 self.setComponentByName(idx, value) 

2259 

2260 except error.PyAsn1Error as exc: 

2261 # duck-typing dict 

2262 raise KeyError(exc) 

2263 

2264 else: 

2265 try: 

2266 self.setComponentByPosition(idx, value) 

2267 

2268 except error.PyAsn1Error as exc: 

2269 # duck-typing list 

2270 raise IndexError(exc) 

2271 

2272 def __contains__(self, key): 

2273 if self._componentTypeLen: 

2274 return key in self.componentType 

2275 else: 

2276 return key in self._dynamicNames 

2277 

2278 def __len__(self): 

2279 return len(self._componentValues) 

2280 

2281 def __iter__(self): 

2282 return iter(self.componentType or self._dynamicNames) 

2283 

2284 # Python dict protocol 

2285 

2286 def values(self): 

2287 for idx in range(self._componentTypeLen or len(self._dynamicNames)): 

2288 yield self[idx] 

2289 

2290 def keys(self): 

2291 return iter(self) 

2292 

2293 def items(self): 

2294 for idx in range(self._componentTypeLen or len(self._dynamicNames)): 

2295 if self._componentTypeLen: 

2296 yield self.componentType[idx].name, self[idx] 

2297 else: 

2298 yield self._dynamicNames[idx], self[idx] 

2299 

2300 def update(self, *iterValue, **mappingValue): 

2301 for k, v in iterValue: 

2302 self[k] = v 

2303 for k in mappingValue: 

2304 self[k] = mappingValue[k] 

2305 

2306 def clear(self): 

2307 """Remove all components and become an empty |ASN.1| value object. 

2308 

2309 Has the same effect on |ASN.1| object as it does on :class:`dict` 

2310 built-in. 

2311 """ 

2312 self._componentValues = [] 

2313 self._dynamicNames = self.DynamicNames() 

2314 return self 

2315 

2316 def reset(self): 

2317 """Remove all components and become a |ASN.1| schema object. 

2318 

2319 See :meth:`isValue` property for more information on the 

2320 distinction between value and schema objects. 

2321 """ 

2322 self._componentValues = noValue 

2323 self._dynamicNames = self.DynamicNames() 

2324 return self 

2325 

2326 @property 

2327 def components(self): 

2328 return self._componentValues 

2329 

2330 def _cloneComponentValues(self, myClone, cloneValueFlag): 

2331 if self._componentValues is noValue: 

2332 return 

2333 

2334 for idx, componentValue in enumerate(self._componentValues): 

2335 if componentValue is not noValue: 

2336 if isinstance(componentValue, base.ConstructedAsn1Type): 

2337 myClone.setComponentByPosition( 

2338 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

2339 ) 

2340 else: 

2341 myClone.setComponentByPosition(idx, componentValue.clone()) 

2342 

2343 def getComponentByName(self, name, default=noValue, instantiate=True): 

2344 """Returns |ASN.1| type component by name. 

2345 

2346 Equivalent to Python :class:`dict` subscription operation (e.g. `[]`). 

2347 

2348 Parameters 

2349 ---------- 

2350 name: :class:`str` 

2351 |ASN.1| type component name 

2352 

2353 Keyword Args 

2354 ------------ 

2355 default: :class:`object` 

2356 If set and requested component is a schema object, return the `default` 

2357 object instead of the requested component. 

2358 

2359 instantiate: :class:`bool` 

2360 If :obj:`True` (default), inner component will be automatically 

2361 instantiated. 

2362 If :obj:`False` either existing component or the :class:`NoValue` 

2363 object will be returned. 

2364 

2365 Returns 

2366 ------- 

2367 : :py:class:`~pyasn1.type.base.PyAsn1Item` 

2368 Instantiate |ASN.1| component type or return existing 

2369 component value 

2370 """ 

2371 if self._componentTypeLen: 

2372 idx = self.componentType.getPositionByName(name) 

2373 else: 

2374 try: 

2375 idx = self._dynamicNames.getPositionByName(name) 

2376 

2377 except KeyError: 

2378 raise error.PyAsn1Error('Name %s not found' % (name,)) 

2379 

2380 return self.getComponentByPosition(idx, default=default, instantiate=instantiate) 

2381 

2382 def setComponentByName(self, name, value=noValue, 

2383 verifyConstraints=True, 

2384 matchTags=True, 

2385 matchConstraints=True): 

2386 """Assign |ASN.1| type component by name. 

2387 

2388 Equivalent to Python :class:`dict` item assignment operation (e.g. `[]`). 

2389 

2390 Parameters 

2391 ---------- 

2392 name: :class:`str` 

2393 |ASN.1| type component name 

2394 

2395 Keyword Args 

2396 ------------ 

2397 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

2398 A Python value to initialize |ASN.1| component with (if *componentType* is set) 

2399 or ASN.1 value object to assign to |ASN.1| component. 

2400 If `value` is not given, schema object will be set as a component. 

2401 

2402 verifyConstraints: :class:`bool` 

2403 If :obj:`False`, skip constraints validation 

2404 

2405 matchTags: :class:`bool` 

2406 If :obj:`False`, skip component tags matching 

2407 

2408 matchConstraints: :class:`bool` 

2409 If :obj:`False`, skip component constraints matching 

2410 

2411 Returns 

2412 ------- 

2413 self 

2414 """ 

2415 if self._componentTypeLen: 

2416 idx = self.componentType.getPositionByName(name) 

2417 else: 

2418 try: 

2419 idx = self._dynamicNames.getPositionByName(name) 

2420 

2421 except KeyError: 

2422 raise error.PyAsn1Error('Name %s not found' % (name,)) 

2423 

2424 return self.setComponentByPosition( 

2425 idx, value, verifyConstraints, matchTags, matchConstraints 

2426 ) 

2427 

2428 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 

2429 """Returns |ASN.1| type component by index. 

2430 

2431 Equivalent to Python sequence subscription operation (e.g. `[]`). 

2432 

2433 Parameters 

2434 ---------- 

2435 idx: :class:`int` 

2436 Component index (zero-based). Must either refer to an existing 

2437 component or (if *componentType* is set) new ASN.1 schema object gets 

2438 instantiated. 

2439 

2440 Keyword Args 

2441 ------------ 

2442 default: :class:`object` 

2443 If set and requested component is a schema object, return the `default` 

2444 object instead of the requested component. 

2445 

2446 instantiate: :class:`bool` 

2447 If :obj:`True` (default), inner component will be automatically 

2448 instantiated. 

2449 If :obj:`False` either existing component or the :class:`NoValue` 

2450 object will be returned. 

2451 

2452 Returns 

2453 ------- 

2454 : :py:class:`~pyasn1.type.base.PyAsn1Item` 

2455 a PyASN1 object 

2456 

2457 Examples 

2458 -------- 

2459 

2460 .. code-block:: python 

2461 

2462 # can also be Set 

2463 class MySequence(Sequence): 

2464 componentType = NamedTypes( 

2465 NamedType('id', OctetString()) 

2466 ) 

2467 

2468 s = MySequence() 

2469 

2470 # returns component #0 with `.isValue` property False 

2471 s.getComponentByPosition(0) 

2472 

2473 # returns None 

2474 s.getComponentByPosition(0, default=None) 

2475 

2476 s.clear() 

2477 

2478 # returns noValue 

2479 s.getComponentByPosition(0, instantiate=False) 

2480 

2481 # sets component #0 to OctetString() ASN.1 schema 

2482 # object and returns it 

2483 s.getComponentByPosition(0, instantiate=True) 

2484 

2485 # sets component #0 to ASN.1 value object 

2486 s.setComponentByPosition(0, 'ABCD') 

2487 

2488 # returns OctetString('ABCD') value object 

2489 s.getComponentByPosition(0, instantiate=False) 

2490 

2491 s.clear() 

2492 

2493 # returns noValue 

2494 s.getComponentByPosition(0, instantiate=False) 

2495 """ 

2496 try: 

2497 if self._componentValues is noValue: 

2498 componentValue = noValue 

2499 

2500 else: 

2501 componentValue = self._componentValues[idx] 

2502 

2503 except IndexError: 

2504 componentValue = noValue 

2505 

2506 if not instantiate: 

2507 if componentValue is noValue or not componentValue.isValue: 

2508 return default 

2509 else: 

2510 return componentValue 

2511 

2512 if componentValue is noValue: 

2513 self.setComponentByPosition(idx) 

2514 

2515 componentValue = self._componentValues[idx] 

2516 

2517 if default is noValue or componentValue.isValue: 

2518 return componentValue 

2519 else: 

2520 return default 

2521 

2522 def setComponentByPosition(self, idx, value=noValue, 

2523 verifyConstraints=True, 

2524 matchTags=True, 

2525 matchConstraints=True): 

2526 """Assign |ASN.1| type component by position. 

2527 

2528 Equivalent to Python sequence item assignment operation (e.g. `[]`). 

2529 

2530 Parameters 

2531 ---------- 

2532 idx : :class:`int` 

2533 Component index (zero-based). Must either refer to existing 

2534 component (if *componentType* is set) or to N+1 component 

2535 otherwise. In the latter case a new component of given ASN.1 

2536 type gets instantiated and appended to |ASN.1| sequence. 

2537 

2538 Keyword Args 

2539 ------------ 

2540 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

2541 A Python value to initialize |ASN.1| component with (if *componentType* is set) 

2542 or ASN.1 value object to assign to |ASN.1| component. 

2543 If `value` is not given, schema object will be set as a component. 

2544 

2545 verifyConstraints : :class:`bool` 

2546 If :obj:`False`, skip constraints validation 

2547 

2548 matchTags: :class:`bool` 

2549 If :obj:`False`, skip component tags matching 

2550 

2551 matchConstraints: :class:`bool` 

2552 If :obj:`False`, skip component constraints matching 

2553 

2554 Returns 

2555 ------- 

2556 self 

2557 """ 

2558 componentType = self.componentType 

2559 componentTypeLen = self._componentTypeLen 

2560 

2561 if self._componentValues is noValue: 

2562 componentValues = [] 

2563 

2564 else: 

2565 componentValues = self._componentValues 

2566 

2567 try: 

2568 currentValue = componentValues[idx] 

2569 

2570 except IndexError: 

2571 currentValue = noValue 

2572 if componentTypeLen: 

2573 if componentTypeLen < idx: 

2574 raise error.PyAsn1Error('component index out of range') 

2575 

2576 componentValues = [noValue] * componentTypeLen 

2577 

2578 if value is noValue: 

2579 if componentTypeLen: 

2580 value = componentType.getTypeByPosition(idx) 

2581 if isinstance(value, base.ConstructedAsn1Type): 

2582 value = value.clone(cloneValueFlag=componentType[idx].isDefaulted) 

2583 

2584 elif currentValue is noValue: 

2585 raise error.PyAsn1Error('Component type not defined') 

2586 

2587 elif not isinstance(value, base.Asn1Item): 

2588 if componentTypeLen: 

2589 subComponentType = componentType.getTypeByPosition(idx) 

2590 if isinstance(subComponentType, base.SimpleAsn1Type): 

2591 value = subComponentType.clone(value=value) 

2592 

2593 else: 

2594 raise error.PyAsn1Error('%s can cast only scalar values' % componentType.__class__.__name__) 

2595 

2596 elif currentValue is not noValue and isinstance(currentValue, base.SimpleAsn1Type): 

2597 value = currentValue.clone(value=value) 

2598 

2599 else: 

2600 raise error.PyAsn1Error('%s undefined component type' % componentType.__class__.__name__) 

2601 

2602 elif ((verifyConstraints or matchTags or matchConstraints) and 

2603 componentTypeLen): 

2604 subComponentType = componentType.getTypeByPosition(idx) 

2605 if subComponentType is not noValue: 

2606 subtypeChecker = (self.strictConstraints and 

2607 subComponentType.isSameTypeWith or 

2608 subComponentType.isSuperTypeOf) 

2609 

2610 if not subtypeChecker(value, verifyConstraints and matchTags, 

2611 verifyConstraints and matchConstraints): 

2612 if not componentType[idx].openType: 

2613 raise error.PyAsn1Error('Component value is tag-incompatible: %r vs %r' % (value, componentType)) 

2614 

2615 if componentTypeLen or idx in self._dynamicNames: 

2616 componentValues[idx] = value 

2617 

2618 elif len(componentValues) == idx: 

2619 componentValues.append(value) 

2620 self._dynamicNames.addField(idx) 

2621 

2622 else: 

2623 raise error.PyAsn1Error('Component index out of range') 

2624 

2625 self._componentValues = componentValues 

2626 

2627 return self 

2628 

2629 @property 

2630 def isValue(self): 

2631 """Indicate that |ASN.1| object represents ASN.1 value. 

2632 

2633 If *isValue* is :obj:`False` then this object represents just ASN.1 schema. 

2634 

2635 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, 

2636 this object can also be used like a Python built-in object (e.g. 

2637 :class:`int`, :class:`str`, :class:`dict` etc.). 

2638 

2639 Returns 

2640 ------- 

2641 : :class:`bool` 

2642 :obj:`False` if object represents just ASN.1 schema. 

2643 :obj:`True` if object represents ASN.1 schema and can be used as a 

2644 normal value. 

2645 

2646 Note 

2647 ---- 

2648 There is an important distinction between PyASN1 schema and value objects. 

2649 The PyASN1 schema objects can only participate in ASN.1 schema-related 

2650 operations (e.g. defining or testing the structure of the data). Most 

2651 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 

2652 encoding/decoding serialised ASN.1 contents. 

2653 

2654 The PyASN1 value objects can **additionally** participate in many operations 

2655 involving regular Python objects (e.g. arithmetic, comprehension etc). 

2656 

2657 It is sufficient for |ASN.1| objects to have all non-optional and non-defaulted 

2658 components being value objects to be considered as a value objects as a whole. 

2659 In other words, even having one or more optional components not turned into 

2660 value objects, |ASN.1| object is still considered as a value object. Defaulted 

2661 components are normally value objects by default. 

2662 """ 

2663 if self._componentValues is noValue: 

2664 return False 

2665 

2666 componentType = self.componentType 

2667 

2668 if componentType: 

2669 for idx, subComponentType in enumerate(componentType.namedTypes): 

2670 if subComponentType.isDefaulted or subComponentType.isOptional: 

2671 continue 

2672 

2673 if not self._componentValues: 

2674 return False 

2675 

2676 componentValue = self._componentValues[idx] 

2677 if componentValue is noValue or not componentValue.isValue: 

2678 return False 

2679 

2680 else: 

2681 for componentValue in self._componentValues: 

2682 if componentValue is noValue or not componentValue.isValue: 

2683 return False 

2684 

2685 return True 

2686 

2687 @property 

2688 def isInconsistent(self): 

2689 """Run necessary checks to ensure |ASN.1| object consistency. 

2690 

2691 Default action is to verify |ASN.1| object against constraints imposed 

2692 by `subtypeSpec`. 

2693 

2694 Raises 

2695 ------ 

2696 :py:class:`~pyasn1.error.PyAsn1tError` on any inconsistencies found 

2697 """ 

2698 if self.componentType is noValue or not self.subtypeSpec: 

2699 return False 

2700 

2701 if self._componentValues is noValue: 

2702 return True 

2703 

2704 mapping = {} 

2705 

2706 for idx, value in enumerate(self._componentValues): 

2707 # Absent fields are not in the mapping 

2708 if value is noValue: 

2709 continue 

2710 

2711 name = self.componentType.getNameByPosition(idx) 

2712 

2713 mapping[name] = value 

2714 

2715 try: 

2716 # Represent Sequence/Set as a bare dict to constraints chain 

2717 self.subtypeSpec(mapping) 

2718 

2719 except error.PyAsn1Error as exc: 

2720 return exc 

2721 

2722 return False 

2723 

2724 def prettyPrint(self, scope=0): 

2725 """Return an object representation string. 

2726 

2727 Returns 

2728 ------- 

2729 : :class:`str` 

2730 Human-friendly object representation. 

2731 """ 

2732 scope += 1 

2733 representation = self.__class__.__name__ + ':\n' 

2734 for idx, componentValue in enumerate(self._componentValues): 

2735 if componentValue is not noValue and componentValue.isValue: 

2736 representation += ' ' * scope 

2737 if self.componentType: 

2738 representation += self.componentType.getNameByPosition(idx) 

2739 else: 

2740 representation += self._dynamicNames.getNameByPosition(idx) 

2741 representation = '%s=%s\n' % ( 

2742 representation, componentValue.prettyPrint(scope) 

2743 ) 

2744 return representation 

2745 

2746 def prettyPrintType(self, scope=0): 

2747 scope += 1 

2748 representation = '%s -> %s {\n' % (self.tagSet, self.__class__.__name__) 

2749 for idx, componentType in enumerate(self.componentType.values() or self._componentValues): 

2750 representation += ' ' * scope 

2751 if self.componentType: 

2752 representation += '"%s"' % self.componentType.getNameByPosition(idx) 

2753 else: 

2754 representation += '"%s"' % self._dynamicNames.getNameByPosition(idx) 

2755 representation = '%s = %s\n' % ( 

2756 representation, componentType.prettyPrintType(scope) 

2757 ) 

2758 return representation + '\n' + ' ' * (scope - 1) + '}' 

2759 

2760 # backward compatibility 

2761 

2762 def setDefaultComponents(self): 

2763 return self 

2764 

2765 def getComponentType(self): 

2766 if self._componentTypeLen: 

2767 return self.componentType 

2768 

2769 def getNameByPosition(self, idx): 

2770 if self._componentTypeLen: 

2771 return self.componentType[idx].name 

2772 

2773class Sequence(SequenceAndSetBase): 

2774 __doc__ = SequenceAndSetBase.__doc__ 

2775 

2776 #: Set (on class, not on instance) or return a 

2777 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

2778 #: associated with |ASN.1| type. 

2779 tagSet = tag.initTagSet( 

2780 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x10) 

2781 ) 

2782 

2783 #: Set (on class, not on instance) or return a 

2784 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

2785 #: imposing constraints on |ASN.1| type initialization values. 

2786 subtypeSpec = constraint.ConstraintsIntersection() 

2787 

2788 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 

2789 #: object imposing size constraint on |ASN.1| objects 

2790 componentType = namedtype.NamedTypes() 

2791 

2792 # Disambiguation ASN.1 types identification 

2793 typeId = SequenceAndSetBase.getTypeId() 

2794 

2795 # backward compatibility 

2796 

2797 def getComponentTagMapNearPosition(self, idx): 

2798 if self.componentType: 

2799 return self.componentType.getTagMapNearPosition(idx) 

2800 

2801 def getComponentPositionNearType(self, tagSet, idx): 

2802 if self.componentType: 

2803 return self.componentType.getPositionNearType(tagSet, idx) 

2804 else: 

2805 return idx 

2806 

2807 

2808class Set(SequenceAndSetBase): 

2809 __doc__ = SequenceAndSetBase.__doc__ 

2810 

2811 #: Set (on class, not on instance) or return a 

2812 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

2813 #: associated with |ASN.1| type. 

2814 tagSet = tag.initTagSet( 

2815 tag.Tag(tag.tagClassUniversal, tag.tagFormatConstructed, 0x11) 

2816 ) 

2817 

2818 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 

2819 #: object representing ASN.1 type allowed within |ASN.1| type 

2820 componentType = namedtype.NamedTypes() 

2821 

2822 #: Set (on class, not on instance) or return a 

2823 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

2824 #: imposing constraints on |ASN.1| type initialization values. 

2825 subtypeSpec = constraint.ConstraintsIntersection() 

2826 

2827 # Disambiguation ASN.1 types identification 

2828 typeId = SequenceAndSetBase.getTypeId() 

2829 

2830 def getComponent(self, innerFlag=False): 

2831 return self 

2832 

2833 def getComponentByType(self, tagSet, default=noValue, 

2834 instantiate=True, innerFlag=False): 

2835 """Returns |ASN.1| type component by ASN.1 tag. 

2836 

2837 Parameters 

2838 ---------- 

2839 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 

2840 Object representing ASN.1 tags to identify one of 

2841 |ASN.1| object component 

2842 

2843 Keyword Args 

2844 ------------ 

2845 default: :class:`object` 

2846 If set and requested component is a schema object, return the `default` 

2847 object instead of the requested component. 

2848 

2849 instantiate: :class:`bool` 

2850 If :obj:`True` (default), inner component will be automatically 

2851 instantiated. 

2852 If :obj:`False` either existing component or the :class:`noValue` 

2853 object will be returned. 

2854 

2855 Returns 

2856 ------- 

2857 : :py:class:`~pyasn1.type.base.PyAsn1Item` 

2858 a pyasn1 object 

2859 """ 

2860 componentValue = self.getComponentByPosition( 

2861 self.componentType.getPositionByType(tagSet), 

2862 default=default, instantiate=instantiate 

2863 ) 

2864 if innerFlag and isinstance(componentValue, Set): 

2865 # get inner component by inner tagSet 

2866 return componentValue.getComponent(innerFlag=True) 

2867 else: 

2868 # get outer component by inner tagSet 

2869 return componentValue 

2870 

2871 def setComponentByType(self, tagSet, value=noValue, 

2872 verifyConstraints=True, 

2873 matchTags=True, 

2874 matchConstraints=True, 

2875 innerFlag=False): 

2876 """Assign |ASN.1| type component by ASN.1 tag. 

2877 

2878 Parameters 

2879 ---------- 

2880 tagSet : :py:class:`~pyasn1.type.tag.TagSet` 

2881 Object representing ASN.1 tags to identify one of 

2882 |ASN.1| object component 

2883 

2884 Keyword Args 

2885 ------------ 

2886 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

2887 A Python value to initialize |ASN.1| component with (if *componentType* is set) 

2888 or ASN.1 value object to assign to |ASN.1| component. 

2889 If `value` is not given, schema object will be set as a component. 

2890 

2891 verifyConstraints : :class:`bool` 

2892 If :obj:`False`, skip constraints validation 

2893 

2894 matchTags: :class:`bool` 

2895 If :obj:`False`, skip component tags matching 

2896 

2897 matchConstraints: :class:`bool` 

2898 If :obj:`False`, skip component constraints matching 

2899 

2900 innerFlag: :class:`bool` 

2901 If :obj:`True`, search for matching *tagSet* recursively. 

2902 

2903 Returns 

2904 ------- 

2905 self 

2906 """ 

2907 idx = self.componentType.getPositionByType(tagSet) 

2908 

2909 if innerFlag: # set inner component by inner tagSet 

2910 componentType = self.componentType.getTypeByPosition(idx) 

2911 

2912 if componentType.tagSet: 

2913 return self.setComponentByPosition( 

2914 idx, value, verifyConstraints, matchTags, matchConstraints 

2915 ) 

2916 else: 

2917 componentType = self.getComponentByPosition(idx) 

2918 return componentType.setComponentByType( 

2919 tagSet, value, verifyConstraints, matchTags, matchConstraints, innerFlag=innerFlag 

2920 ) 

2921 else: # set outer component by inner tagSet 

2922 return self.setComponentByPosition( 

2923 idx, value, verifyConstraints, matchTags, matchConstraints 

2924 ) 

2925 

2926 @property 

2927 def componentTagMap(self): 

2928 if self.componentType: 

2929 return self.componentType.tagMapUnique 

2930 

2931 

2932class Choice(Set): 

2933 """Create |ASN.1| schema or value object. 

2934 

2935 |ASN.1| class is based on :class:`~pyasn1.type.base.ConstructedAsn1Type`, 

2936 its objects are mutable and duck-type Python :class:`list` objects. 

2937 

2938 Keyword Args 

2939 ------------ 

2940 componentType: :py:class:`~pyasn1.type.namedtype.NamedType` 

2941 Object holding named ASN.1 types allowed within this collection 

2942 

2943 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

2944 Object representing non-default ASN.1 tag(s) 

2945 

2946 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

2947 Object representing non-default ASN.1 subtype constraint(s). Constraints 

2948 verification for |ASN.1| type can only occur on explicit 

2949 `.isInconsistent` call. 

2950 

2951 Examples 

2952 -------- 

2953 

2954 .. code-block:: python 

2955 

2956 class Afters(Choice): 

2957 ''' 

2958 ASN.1 specification: 

2959 

2960 Afters ::= CHOICE { 

2961 cheese [0] IA5String, 

2962 dessert [1] IA5String 

2963 } 

2964 ''' 

2965 componentType = NamedTypes( 

2966 NamedType('cheese', IA5String().subtype( 

2967 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 

2968 ), 

2969 NamedType('dessert', IA5String().subtype( 

2970 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 

2971 ) 

2972 ) 

2973 

2974 afters = Afters() 

2975 afters['cheese'] = 'Mascarpone' 

2976 """ 

2977 #: Set (on class, not on instance) or return a 

2978 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

2979 #: associated with |ASN.1| type. 

2980 tagSet = tag.TagSet() # untagged 

2981 

2982 #: Default collection of ASN.1 types of component (e.g. :py:class:`~pyasn1.type.namedtype.NamedType`) 

2983 #: object representing ASN.1 type allowed within |ASN.1| type 

2984 componentType = namedtype.NamedTypes() 

2985 

2986 #: Set (on class, not on instance) or return a 

2987 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

2988 #: imposing constraints on |ASN.1| type initialization values. 

2989 subtypeSpec = constraint.ConstraintsIntersection( 

2990 constraint.ValueSizeConstraint(1, 1) 

2991 ) 

2992 

2993 # Disambiguation ASN.1 types identification 

2994 typeId = Set.getTypeId() 

2995 

2996 _currentIdx = None 

2997 

2998 def __eq__(self, other): 

2999 if self._componentValues: 

3000 return self._componentValues[self._currentIdx] == other 

3001 return NotImplemented 

3002 

3003 def __ne__(self, other): 

3004 if self._componentValues: 

3005 return self._componentValues[self._currentIdx] != other 

3006 return NotImplemented 

3007 

3008 def __lt__(self, other): 

3009 if self._componentValues: 

3010 return self._componentValues[self._currentIdx] < other 

3011 return NotImplemented 

3012 

3013 def __le__(self, other): 

3014 if self._componentValues: 

3015 return self._componentValues[self._currentIdx] <= other 

3016 return NotImplemented 

3017 

3018 def __gt__(self, other): 

3019 if self._componentValues: 

3020 return self._componentValues[self._currentIdx] > other 

3021 return NotImplemented 

3022 

3023 def __ge__(self, other): 

3024 if self._componentValues: 

3025 return self._componentValues[self._currentIdx] >= other 

3026 return NotImplemented 

3027 

3028 def __bool__(self): 

3029 return bool(self._componentValues) 

3030 

3031 def __len__(self): 

3032 return self._currentIdx is not None and 1 or 0 

3033 

3034 def __contains__(self, key): 

3035 if self._currentIdx is None: 

3036 return False 

3037 return key == self.componentType[self._currentIdx].getName() 

3038 

3039 def __iter__(self): 

3040 if self._currentIdx is None: 

3041 raise StopIteration 

3042 yield self.componentType[self._currentIdx].getName() 

3043 

3044 # Python dict protocol 

3045 

3046 def values(self): 

3047 if self._currentIdx is not None: 

3048 yield self._componentValues[self._currentIdx] 

3049 

3050 def keys(self): 

3051 if self._currentIdx is not None: 

3052 yield self.componentType[self._currentIdx].getName() 

3053 

3054 def items(self): 

3055 if self._currentIdx is not None: 

3056 yield self.componentType[self._currentIdx].getName(), self[self._currentIdx] 

3057 

3058 def checkConsistency(self): 

3059 if self._currentIdx is None: 

3060 raise error.PyAsn1Error('Component not chosen') 

3061 

3062 def _cloneComponentValues(self, myClone, cloneValueFlag): 

3063 try: 

3064 component = self.getComponent() 

3065 except error.PyAsn1Error: 

3066 pass 

3067 else: 

3068 if isinstance(component, Choice): 

3069 tagSet = component.effectiveTagSet 

3070 else: 

3071 tagSet = component.tagSet 

3072 if isinstance(component, base.ConstructedAsn1Type): 

3073 myClone.setComponentByType( 

3074 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 

3075 ) 

3076 else: 

3077 myClone.setComponentByType(tagSet, component.clone()) 

3078 

3079 def getComponentByPosition(self, idx, default=noValue, instantiate=True): 

3080 __doc__ = Set.__doc__ 

3081 

3082 if self._currentIdx is None or self._currentIdx != idx: 

3083 return Set.getComponentByPosition(self, idx, default=default, 

3084 instantiate=instantiate) 

3085 

3086 return self._componentValues[idx] 

3087 

3088 def setComponentByPosition(self, idx, value=noValue, 

3089 verifyConstraints=True, 

3090 matchTags=True, 

3091 matchConstraints=True): 

3092 """Assign |ASN.1| type component by position. 

3093 

3094 Equivalent to Python sequence item assignment operation (e.g. `[]`). 

3095 

3096 Parameters 

3097 ---------- 

3098 idx: :class:`int` 

3099 Component index (zero-based). Must either refer to existing 

3100 component or to N+1 component. In the latter case a new component 

3101 type gets instantiated (if *componentType* is set, or given ASN.1 

3102 object is taken otherwise) and appended to the |ASN.1| sequence. 

3103 

3104 Keyword Args 

3105 ------------ 

3106 value: :class:`object` or :py:class:`~pyasn1.type.base.PyAsn1Item` derivative 

3107 A Python value to initialize |ASN.1| component with (if *componentType* is set) 

3108 or ASN.1 value object to assign to |ASN.1| component. Once a new value is 

3109 set to *idx* component, previous value is dropped. 

3110 If `value` is not given, schema object will be set as a component. 

3111 

3112 verifyConstraints : :class:`bool` 

3113 If :obj:`False`, skip constraints validation 

3114 

3115 matchTags: :class:`bool` 

3116 If :obj:`False`, skip component tags matching 

3117 

3118 matchConstraints: :class:`bool` 

3119 If :obj:`False`, skip component constraints matching 

3120 

3121 Returns 

3122 ------- 

3123 self 

3124 """ 

3125 oldIdx = self._currentIdx 

3126 Set.setComponentByPosition(self, idx, value, verifyConstraints, matchTags, matchConstraints) 

3127 self._currentIdx = idx 

3128 if oldIdx is not None and oldIdx != idx: 

3129 self._componentValues[oldIdx] = noValue 

3130 return self 

3131 

3132 @property 

3133 def effectiveTagSet(self): 

3134 """Return a :class:`~pyasn1.type.tag.TagSet` object of the currently initialized component or self (if |ASN.1| is tagged).""" 

3135 if self.tagSet: 

3136 return self.tagSet 

3137 else: 

3138 component = self.getComponent() 

3139 return component.effectiveTagSet 

3140 

3141 @property 

3142 def tagMap(self): 

3143 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 

3144 ASN.1 tags to ASN.1 objects contained within callee. 

3145 """ 

3146 if self.tagSet: 

3147 return Set.tagMap.fget(self) 

3148 else: 

3149 return self.componentType.tagMapUnique 

3150 

3151 def getComponent(self, innerFlag=False): 

3152 """Return currently assigned component of the |ASN.1| object. 

3153 

3154 Returns 

3155 ------- 

3156 : :py:class:`~pyasn1.type.base.PyAsn1Item` 

3157 a PyASN1 object 

3158 """ 

3159 if self._currentIdx is None: 

3160 raise error.PyAsn1Error('Component not chosen') 

3161 else: 

3162 c = self._componentValues[self._currentIdx] 

3163 if innerFlag and isinstance(c, Choice): 

3164 return c.getComponent(innerFlag) 

3165 else: 

3166 return c 

3167 

3168 def getName(self, innerFlag=False): 

3169 """Return the name of currently assigned component of the |ASN.1| object. 

3170 

3171 Returns 

3172 ------- 

3173 : :py:class:`str` 

3174 |ASN.1| component name 

3175 """ 

3176 if self._currentIdx is None: 

3177 raise error.PyAsn1Error('Component not chosen') 

3178 else: 

3179 if innerFlag: 

3180 c = self._componentValues[self._currentIdx] 

3181 if isinstance(c, Choice): 

3182 return c.getName(innerFlag) 

3183 return self.componentType.getNameByPosition(self._currentIdx) 

3184 

3185 @property 

3186 def isValue(self): 

3187 """Indicate that |ASN.1| object represents ASN.1 value. 

3188 

3189 If *isValue* is :obj:`False` then this object represents just ASN.1 schema. 

3190 

3191 If *isValue* is :obj:`True` then, in addition to its ASN.1 schema features, 

3192 this object can also be used like a Python built-in object (e.g. 

3193 :class:`int`, :class:`str`, :class:`dict` etc.). 

3194 

3195 Returns 

3196 ------- 

3197 : :class:`bool` 

3198 :obj:`False` if object represents just ASN.1 schema. 

3199 :obj:`True` if object represents ASN.1 schema and can be used as a normal 

3200 value. 

3201 

3202 Note 

3203 ---- 

3204 There is an important distinction between PyASN1 schema and value objects. 

3205 The PyASN1 schema objects can only participate in ASN.1 schema-related 

3206 operations (e.g. defining or testing the structure of the data). Most 

3207 obvious uses of ASN.1 schema is to guide serialisation codecs whilst 

3208 encoding/decoding serialised ASN.1 contents. 

3209 

3210 The PyASN1 value objects can **additionally** participate in many operations 

3211 involving regular Python objects (e.g. arithmetic, comprehension etc). 

3212 """ 

3213 if self._currentIdx is None: 

3214 return False 

3215 

3216 componentValue = self._componentValues[self._currentIdx] 

3217 

3218 return componentValue is not noValue and componentValue.isValue 

3219 

3220 def clear(self): 

3221 self._currentIdx = None 

3222 return Set.clear(self) 

3223 

3224 # compatibility stubs 

3225 

3226 def getMinTagSet(self): 

3227 return self.minTagSet 

3228 

3229 

3230class Any(OctetString): 

3231 """Create |ASN.1| schema or value object. 

3232 

3233 |ASN.1| class is based on :class:`~pyasn1.type.base.SimpleAsn1Type`, 

3234 its objects are immutable and duck-type :class:`bytes`. 

3235 When used in Unicode context, |ASN.1| type assumes 

3236 "|encoding|" serialisation. 

3237 

3238 Keyword Args 

3239 ------------ 

3240 value: :class:`unicode`, :class:`str`, :class:`bytes` or |ASN.1| object 

3241 :class:`bytes`, alternatively :class:`str` 

3242 representing character string to be serialised into octets (note 

3243 `encoding` parameter) or |ASN.1| object. 

3244 If `value` is not given, schema object will be created. 

3245 

3246 tagSet: :py:class:`~pyasn1.type.tag.TagSet` 

3247 Object representing non-default ASN.1 tag(s) 

3248 

3249 subtypeSpec: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` 

3250 Object representing non-default ASN.1 subtype constraint(s). Constraints 

3251 verification for |ASN.1| type occurs automatically on object 

3252 instantiation. 

3253 

3254 encoding: :py:class:`str` 

3255 Unicode codec ID to encode/decode 

3256 :class:`str` the payload when |ASN.1| object is used 

3257 in text string context. 

3258 

3259 binValue: :py:class:`str` 

3260 Binary string initializer to use instead of the *value*. 

3261 Example: '10110011'. 

3262 

3263 hexValue: :py:class:`str` 

3264 Hexadecimal string initializer to use instead of the *value*. 

3265 Example: 'DEADBEEF'. 

3266 

3267 Raises 

3268 ------ 

3269 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

3270 On constraint violation or bad initializer. 

3271 

3272 Examples 

3273 -------- 

3274 .. code-block:: python 

3275 

3276 class Error(Sequence): 

3277 ''' 

3278 ASN.1 specification: 

3279 

3280 Error ::= SEQUENCE { 

3281 code INTEGER, 

3282 parameter ANY DEFINED BY code -- Either INTEGER or REAL 

3283 } 

3284 ''' 

3285 componentType=NamedTypes( 

3286 NamedType('code', Integer()), 

3287 NamedType('parameter', Any(), 

3288 openType=OpenType('code', {1: Integer(), 

3289 2: Real()})) 

3290 ) 

3291 

3292 error = Error() 

3293 error['code'] = 1 

3294 error['parameter'] = Integer(1234) 

3295 """ 

3296 #: Set (on class, not on instance) or return a 

3297 #: :py:class:`~pyasn1.type.tag.TagSet` object representing ASN.1 tag(s) 

3298 #: associated with |ASN.1| type. 

3299 tagSet = tag.TagSet() # untagged 

3300 

3301 #: Set (on class, not on instance) or return a 

3302 #: :py:class:`~pyasn1.type.constraint.ConstraintsIntersection` object 

3303 #: imposing constraints on |ASN.1| type initialization values. 

3304 subtypeSpec = constraint.ConstraintsIntersection() 

3305 

3306 # Disambiguation ASN.1 types identification 

3307 typeId = OctetString.getTypeId() 

3308 

3309 @property 

3310 def tagMap(self): 

3311 """"Return a :class:`~pyasn1.type.tagmap.TagMap` object mapping 

3312 ASN.1 tags to ASN.1 objects contained within callee. 

3313 """ 

3314 try: 

3315 return self._tagMap 

3316 

3317 except AttributeError: 

3318 self._tagMap = tagmap.TagMap( 

3319 {self.tagSet: self}, 

3320 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 

3321 self 

3322 ) 

3323 

3324 return self._tagMap 

3325 

3326# XXX 

3327# coercion rules?