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

1274 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 07:30 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

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

5# License: http://snmplabs.com/pyasn1/license.html 

6# 

7import math 

8import sys 

9 

10from pyasn1 import error 

11from pyasn1.codec.ber import eoo 

12from pyasn1.compat import binary 

13from pyasn1.compat import integer 

14from pyasn1.compat import octets 

15from pyasn1.type import base 

16from pyasn1.type import constraint 

17from pyasn1.type import namedtype 

18from pyasn1.type import namedval 

19from pyasn1.type import tag 

20from pyasn1.type import tagmap 

21 

22NoValue = base.NoValue 

23noValue = NoValue() 

24 

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

26 'ObjectIdentifier', 'Real', 'Enumerated', 

27 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf', 

28 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any', 

29 'NoValue', 'noValue'] 

30 

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

32 

33 

34class Integer(base.SimpleAsn1Type): 

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

36 

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

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

39 

40 Keyword Args 

41 ------------ 

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

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

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

45 

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

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

48 

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

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

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

52 instantiation. 

53 

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

55 Object representing non-default symbolic aliases for numbers 

56 

57 Raises 

58 ------ 

59 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

60 On constraint violation or bad initializer. 

61 

62 Examples 

63 -------- 

64 

65 .. code-block:: python 

66 

67 class ErrorCode(Integer): 

68 ''' 

69 ASN.1 specification: 

70 

71 ErrorCode ::= 

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

73 disk-not-formatted(2) } 

74 

75 error ErrorCode ::= disk-full 

76 ''' 

77 namedValues = NamedValues( 

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

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

80 ) 

81 

82 error = ErrorCode('disk-full') 

83 """ 

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

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

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

87 tagSet = tag.initTagSet( 

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

89 ) 

90 

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

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

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

94 subtypeSpec = constraint.ConstraintsIntersection() 

95 

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

97 #: representing symbolic aliases for numbers 

98 namedValues = namedval.NamedValues() 

99 

100 # Optimization for faster codec lookup 

101 typeId = base.SimpleAsn1Type.getTypeId() 

102 

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

104 if 'namedValues' not in kwargs: 

105 kwargs['namedValues'] = self.namedValues 

106 

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

108 

109 def __and__(self, value): 

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

111 

112 def __rand__(self, value): 

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

114 

115 def __or__(self, value): 

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

117 

118 def __ror__(self, value): 

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

120 

121 def __xor__(self, value): 

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

123 

124 def __rxor__(self, value): 

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

126 

127 def __lshift__(self, value): 

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

129 

130 def __rshift__(self, value): 

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

132 

133 def __add__(self, value): 

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

135 

136 def __radd__(self, value): 

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

138 

139 def __sub__(self, value): 

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

141 

142 def __rsub__(self, value): 

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

144 

145 def __mul__(self, value): 

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

147 

148 def __rmul__(self, value): 

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

150 

151 def __mod__(self, value): 

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

153 

154 def __rmod__(self, value): 

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

156 

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

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

159 

160 def __rpow__(self, value): 

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

162 

163 def __floordiv__(self, value): 

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

165 

166 def __rfloordiv__(self, value): 

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

168 

169 if sys.version_info[0] <= 2: 

170 def __div__(self, value): 

171 if isinstance(value, float): 

172 return Real(self._value / value) 

173 else: 

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

175 

176 def __rdiv__(self, value): 

177 if isinstance(value, float): 

178 return Real(value / self._value) 

179 else: 

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

181 else: 

182 def __truediv__(self, value): 

183 return Real(self._value / value) 

184 

185 def __rtruediv__(self, value): 

186 return Real(value / self._value) 

187 

188 def __divmod__(self, value): 

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

190 

191 def __rdivmod__(self, value): 

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

193 

194 __hash__ = base.SimpleAsn1Type.__hash__ 

195 

196 def __int__(self): 

197 return int(self._value) 

198 

199 if sys.version_info[0] <= 2: 

200 def __long__(self): 

201 return long(self._value) 

202 

203 def __float__(self): 

204 return float(self._value) 

205 

206 def __abs__(self): 

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

208 

209 def __index__(self): 

210 return int(self._value) 

211 

212 def __pos__(self): 

213 return self.clone(+self._value) 

214 

215 def __neg__(self): 

216 return self.clone(-self._value) 

217 

218 def __invert__(self): 

219 return self.clone(~self._value) 

220 

221 def __round__(self, n=0): 

222 r = round(self._value, n) 

223 if n: 

224 return self.clone(r) 

225 else: 

226 return r 

227 

228 def __floor__(self): 

229 return math.floor(self._value) 

230 

231 def __ceil__(self): 

232 return math.ceil(self._value) 

233 

234 if sys.version_info[0:2] > (2, 5): 

235 def __trunc__(self): 

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

237 

238 def __lt__(self, value): 

239 return self._value < value 

240 

241 def __le__(self, value): 

242 return self._value <= value 

243 

244 def __eq__(self, value): 

245 return self._value == value 

246 

247 def __ne__(self, value): 

248 return self._value != value 

249 

250 def __gt__(self, value): 

251 return self._value > value 

252 

253 def __ge__(self, value): 

254 return self._value >= value 

255 

256 def prettyIn(self, value): 

257 try: 

258 return int(value) 

259 

260 except ValueError: 

261 try: 

262 return self.namedValues[value] 

263 

264 except KeyError: 

265 raise error.PyAsn1Error( 

266 'Can\'t coerce %r into integer: %s' % (value, sys.exc_info()[1]) 

267 ) 

268 

269 def prettyOut(self, value): 

270 try: 

271 return str(self.namedValues[value]) 

272 

273 except KeyError: 

274 return str(value) 

275 

276 # backward compatibility 

277 

278 def getNamedValues(self): 

279 return self.namedValues 

280 

281 

282class Boolean(Integer): 

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

284 

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

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

287 

288 Keyword Args 

289 ------------ 

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

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

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

293 

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

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

296 

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

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

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

300 instantiation. 

301 

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

303 Object representing non-default symbolic aliases for numbers 

304 

305 Raises 

306 ------ 

307 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

308 On constraint violation or bad initializer. 

309 

310 Examples 

311 -------- 

312 .. code-block:: python 

313 

314 class RoundResult(Boolean): 

315 ''' 

316 ASN.1 specification: 

317 

318 RoundResult ::= BOOLEAN 

319 

320 ok RoundResult ::= TRUE 

321 ko RoundResult ::= FALSE 

322 ''' 

323 ok = RoundResult(True) 

324 ko = RoundResult(False) 

325 """ 

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

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

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

329 tagSet = tag.initTagSet( 

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

331 ) 

332 

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

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

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

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

337 

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

339 #: representing symbolic aliases for numbers 

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

341 

342 # Optimization for faster codec lookup 

343 typeId = Integer.getTypeId() 

344 

345if sys.version_info[0] < 3: 

346 SizedIntegerBase = long 

347else: 

348 SizedIntegerBase = int 

349 

350 

351class SizedInteger(SizedIntegerBase): 

352 bitLength = leadingZeroBits = None 

353 

354 def setBitLength(self, bitLength): 

355 self.bitLength = bitLength 

356 self.leadingZeroBits = max(bitLength - integer.bitLength(self), 0) 

357 return self 

358 

359 def __len__(self): 

360 if self.bitLength is None: 

361 self.setBitLength(integer.bitLength(self)) 

362 

363 return self.bitLength 

364 

365 

366class BitString(base.SimpleAsn1Type): 

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

368 

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

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

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

372 

373 Keyword Args 

374 ------------ 

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

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

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

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

379 

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

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

382 

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

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

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

386 instantiation. 

387 

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

389 Object representing non-default symbolic aliases for numbers 

390 

391 binValue: :py:class:`str` 

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

393 Example: '10110011'. 

394 

395 hexValue: :py:class:`str` 

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

397 Example: 'DEADBEEF'. 

398 

399 Raises 

400 ------ 

401 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

402 On constraint violation or bad initializer. 

403 

404 Examples 

405 -------- 

406 .. code-block:: python 

407 

408 class Rights(BitString): 

409 ''' 

410 ASN.1 specification: 

411 

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

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

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

415 

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

417 group2 Rights ::= '0011'B 

418 group3 Rights ::= '3'H 

419 ''' 

420 namedValues = NamedValues( 

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

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

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

424 ) 

425 

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

427 group2 = Rights('0011') 

428 group3 = Rights(0x3) 

429 """ 

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

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

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

433 tagSet = tag.initTagSet( 

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

435 ) 

436 

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

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

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

440 subtypeSpec = constraint.ConstraintsIntersection() 

441 

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

443 #: representing symbolic aliases for numbers 

444 namedValues = namedval.NamedValues() 

445 

446 # Optimization for faster codec lookup 

447 typeId = base.SimpleAsn1Type.getTypeId() 

448 

449 defaultBinValue = defaultHexValue = noValue 

450 

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

452 if value is noValue: 

453 if kwargs: 

454 try: 

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

456 

457 except KeyError: 

458 pass 

459 

460 try: 

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

462 

463 except KeyError: 

464 pass 

465 

466 if value is noValue: 

467 if self.defaultBinValue is not noValue: 

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

469 

470 elif self.defaultHexValue is not noValue: 

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

472 

473 if 'namedValues' not in kwargs: 

474 kwargs['namedValues'] = self.namedValues 

475 

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

477 

478 def __str__(self): 

479 return self.asBinary() 

480 

481 def __eq__(self, other): 

482 other = self.prettyIn(other) 

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

484 

485 def __ne__(self, other): 

486 other = self.prettyIn(other) 

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

488 

489 def __lt__(self, other): 

490 other = self.prettyIn(other) 

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

492 

493 def __le__(self, other): 

494 other = self.prettyIn(other) 

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

496 

497 def __gt__(self, other): 

498 other = self.prettyIn(other) 

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

500 

501 def __ge__(self, other): 

502 other = self.prettyIn(other) 

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

504 

505 # Immutable sequence object protocol 

506 

507 def __len__(self): 

508 return len(self._value) 

509 

510 def __getitem__(self, i): 

511 if i.__class__ is slice: 

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

513 else: 

514 length = len(self._value) - 1 

515 if i > length or i < 0: 

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

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

518 

519 def __iter__(self): 

520 length = len(self._value) 

521 while length: 

522 length -= 1 

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

524 

525 def __reversed__(self): 

526 return reversed(tuple(self)) 

527 

528 # arithmetic operators 

529 

530 def __add__(self, value): 

531 value = self.prettyIn(value) 

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

533 

534 def __radd__(self, value): 

535 value = self.prettyIn(value) 

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

537 

538 def __mul__(self, value): 

539 bitString = self._value 

540 while value > 1: 

541 bitString <<= len(self._value) 

542 bitString |= self._value 

543 value -= 1 

544 return self.clone(bitString) 

545 

546 def __rmul__(self, value): 

547 return self * value 

548 

549 def __lshift__(self, count): 

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

551 

552 def __rshift__(self, count): 

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

554 

555 def __int__(self): 

556 return self._value 

557 

558 def __float__(self): 

559 return float(self._value) 

560 

561 if sys.version_info[0] < 3: 

562 def __long__(self): 

563 return self._value 

564 

565 def asNumbers(self): 

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

567 

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

569 will be left-padded with zeros. 

570 """ 

571 return tuple(octets.octs2ints(self.asOctets())) 

572 

573 def asOctets(self): 

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

575 

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

577 will be left-padded with zeros. 

578 """ 

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

580 

581 def asInteger(self): 

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

583 """ 

584 return self._value 

585 

586 def asBinary(self): 

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

588 """ 

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

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

591 

592 @classmethod 

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

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

595 

596 Parameters 

597 ---------- 

598 value: :class:`str` 

599 Text string like 'DEADBEEF' 

600 """ 

601 try: 

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

603 

604 except ValueError: 

605 raise error.PyAsn1Error('%s.fromHexString() error: %s' % (cls.__name__, sys.exc_info()[1])) 

606 

607 if prepend is not None: 

608 value = SizedInteger( 

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

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

611 

612 if not internalFormat: 

613 value = cls(value) 

614 

615 return value 

616 

617 @classmethod 

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

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

620 

621 Parameters 

622 ---------- 

623 value: :class:`str` 

624 Text string like '1010111' 

625 """ 

626 try: 

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

628 

629 except ValueError: 

630 raise error.PyAsn1Error('%s.fromBinaryString() error: %s' % (cls.__name__, sys.exc_info()[1])) 

631 

632 if prepend is not None: 

633 value = SizedInteger( 

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

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

636 

637 if not internalFormat: 

638 value = cls(value) 

639 

640 return value 

641 

642 @classmethod 

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

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

645 

646 Parameters 

647 ---------- 

648 value: :class:`str` (Py2) or :class:`bytes` (Py3) 

649 Text string like '\\\\x01\\\\xff' (Py2) or b'\\\\x01\\\\xff' (Py3) 

650 """ 

651 value = SizedInteger(integer.from_bytes(value) >> padding).setBitLength(len(value) * 8 - padding) 

652 

653 if prepend is not None: 

654 value = SizedInteger( 

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

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

657 

658 if not internalFormat: 

659 value = cls(value) 

660 

661 return value 

662 

663 def prettyIn(self, value): 

664 if isinstance(value, SizedInteger): 

665 return value 

666 elif octets.isStringType(value): 

667 if not value: 

668 return SizedInteger(0).setBitLength(0) 

669 

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

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

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

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

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

675 else: 

676 raise error.PyAsn1Error( 

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

678 ) 

679 

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

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

682 

683 try: 

684 

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

686 

687 except KeyError: 

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

689 

690 rightmostPosition = max(bitPositions) 

691 

692 number = 0 

693 for bitPosition in bitPositions: 

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

695 

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

697 

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

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

700 

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

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

703 

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

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

706 

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

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

709 

710 elif isinstance(value, BitString): 

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

712 

713 elif isinstance(value, intTypes): 

714 return SizedInteger(value) 

715 

716 else: 

717 raise error.PyAsn1Error( 

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

719 ) 

720 

721 

722try: 

723 # noinspection PyStatementEffect 

724 all 

725 

726except NameError: # Python 2.4 

727 # noinspection PyShadowingBuiltins 

728 def all(iterable): 

729 for element in iterable: 

730 if not element: 

731 return False 

732 return True 

733 

734 

735class OctetString(base.SimpleAsn1Type): 

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

737 

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

739 objects are immutable and duck-type Python 2 :class:`str` or 

740 Python 3 :class:`bytes`. When used in Unicode context, |ASN.1| type 

741 assumes "|encoding|" serialisation. 

742 

743 Keyword Args 

744 ------------ 

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

746 class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively 

747 class:`unicode` object (Python 2) or :class:`str` (Python 3) 

748 representing character string to be serialised into octets 

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

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

751 

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

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

754 

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

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

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

758 instantiation. 

759 

760 encoding: :py:class:`str` 

761 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or 

762 :class:`str` (Python 3) the payload when |ASN.1| object is used 

763 in text string context. 

764 

765 binValue: :py:class:`str` 

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

767 Example: '10110011'. 

768 

769 hexValue: :py:class:`str` 

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

771 Example: 'DEADBEEF'. 

772 

773 Raises 

774 ------ 

775 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

776 On constraint violation or bad initializer. 

777 

778 Examples 

779 -------- 

780 .. code-block:: python 

781 

782 class Icon(OctetString): 

783 ''' 

784 ASN.1 specification: 

785 

786 Icon ::= OCTET STRING 

787 

788 icon1 Icon ::= '001100010011001000110011'B 

789 icon2 Icon ::= '313233'H 

790 ''' 

791 icon1 = Icon.fromBinaryString('001100010011001000110011') 

792 icon2 = Icon.fromHexString('313233') 

793 """ 

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

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

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

797 tagSet = tag.initTagSet( 

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

799 ) 

800 

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

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

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

804 subtypeSpec = constraint.ConstraintsIntersection() 

805 

806 # Optimization for faster codec lookup 

807 typeId = base.SimpleAsn1Type.getTypeId() 

808 

809 defaultBinValue = defaultHexValue = noValue 

810 encoding = 'iso-8859-1' 

811 

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

813 if kwargs: 

814 if value is noValue: 

815 try: 

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

817 

818 except KeyError: 

819 pass 

820 

821 try: 

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

823 

824 except KeyError: 

825 pass 

826 

827 if value is noValue: 

828 if self.defaultBinValue is not noValue: 

829 value = self.fromBinaryString(self.defaultBinValue) 

830 

831 elif self.defaultHexValue is not noValue: 

832 value = self.fromHexString(self.defaultHexValue) 

833 

834 if 'encoding' not in kwargs: 

835 kwargs['encoding'] = self.encoding 

836 

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

838 

839 if sys.version_info[0] <= 2: 

840 def prettyIn(self, value): 

841 if isinstance(value, str): 

842 return value 

843 

844 elif isinstance(value, unicode): 

845 try: 

846 return value.encode(self.encoding) 

847 

848 except (LookupError, UnicodeEncodeError): 

849 exc = sys.exc_info()[1] 

850 raise error.PyAsn1UnicodeEncodeError( 

851 "Can't encode string '%s' with codec " 

852 "%s" % (value, self.encoding), exc 

853 ) 

854 

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

856 try: 

857 return ''.join([chr(x) for x in value]) 

858 

859 except ValueError: 

860 raise error.PyAsn1Error( 

861 "Bad %s initializer '%s'" % (self.__class__.__name__, value) 

862 ) 

863 

864 else: 

865 return str(value) 

866 

867 def __str__(self): 

868 return str(self._value) 

869 

870 def __unicode__(self): 

871 try: 

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

873 

874 except UnicodeDecodeError: 

875 exc = sys.exc_info()[1] 

876 raise error.PyAsn1UnicodeDecodeError( 

877 "Can't decode string '%s' with codec " 

878 "%s" % (self._value, self.encoding), exc 

879 ) 

880 

881 def asOctets(self): 

882 return str(self._value) 

883 

884 def asNumbers(self): 

885 return tuple([ord(x) for x in self._value]) 

886 

887 else: 

888 def prettyIn(self, value): 

889 if isinstance(value, bytes): 

890 return value 

891 

892 elif isinstance(value, str): 

893 try: 

894 return value.encode(self.encoding) 

895 

896 except UnicodeEncodeError: 

897 exc = sys.exc_info()[1] 

898 raise error.PyAsn1UnicodeEncodeError( 

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

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

901 ) 

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

903 return value.asOctets() 

904 

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

906 return self.prettyIn(str(value)) 

907 

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

909 return self.prettyIn(bytes(value)) 

910 

911 else: 

912 return bytes(value) 

913 

914 def __str__(self): 

915 try: 

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

917 

918 except UnicodeDecodeError: 

919 exc = sys.exc_info()[1] 

920 raise error.PyAsn1UnicodeDecodeError( 

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

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

923 self.__class__.__name__), exc 

924 ) 

925 

926 def __bytes__(self): 

927 return bytes(self._value) 

928 

929 def asOctets(self): 

930 return bytes(self._value) 

931 

932 def asNumbers(self): 

933 return tuple(self._value) 

934 

935 # 

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

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

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

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

940 # text (Py3) representations. 

941 # 

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

943 # reversed to preserve the original behaviour. 

944 # 

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

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

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

948 # the `.asOctets()` method. 

949 # 

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

951 # 

952 

953 def prettyOut(self, value): 

954 return value 

955 

956 def prettyPrint(self, scope=0): 

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

958 value = self.prettyOut(self._value) 

959 

960 if value is not self._value: 

961 return value 

962 

963 numbers = self.asNumbers() 

964 

965 for x in numbers: 

966 # hexify if needed 

967 if x < 32 or x > 126: 

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

969 else: 

970 # this prevents infinite recursion 

971 return OctetString.__str__(self) 

972 

973 @staticmethod 

974 def fromBinaryString(value): 

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

976 

977 Parameters 

978 ---------- 

979 value: :class:`str` 

980 Text string like '1010111' 

981 """ 

982 bitNo = 8 

983 byte = 0 

984 r = [] 

985 for v in value: 

986 if bitNo: 

987 bitNo -= 1 

988 else: 

989 bitNo = 7 

990 r.append(byte) 

991 byte = 0 

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

993 v = int(v) 

994 else: 

995 raise error.PyAsn1Error( 

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

997 ) 

998 byte |= v << bitNo 

999 

1000 r.append(byte) 

1001 

1002 return octets.ints2octs(r) 

1003 

1004 @staticmethod 

1005 def fromHexString(value): 

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

1007 

1008 Parameters 

1009 ---------- 

1010 value: :class:`str` 

1011 Text string like 'DEADBEEF' 

1012 """ 

1013 r = [] 

1014 p = [] 

1015 for v in value: 

1016 if p: 

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

1018 p = None 

1019 else: 

1020 p = v 

1021 if p: 

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

1023 

1024 return octets.ints2octs(r) 

1025 

1026 # Immutable sequence object protocol 

1027 

1028 def __len__(self): 

1029 return len(self._value) 

1030 

1031 def __getitem__(self, i): 

1032 if i.__class__ is slice: 

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

1034 else: 

1035 return self._value[i] 

1036 

1037 def __iter__(self): 

1038 return iter(self._value) 

1039 

1040 def __contains__(self, value): 

1041 return value in self._value 

1042 

1043 def __add__(self, value): 

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

1045 

1046 def __radd__(self, value): 

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

1048 

1049 def __mul__(self, value): 

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

1051 

1052 def __rmul__(self, value): 

1053 return self * value 

1054 

1055 def __int__(self): 

1056 return int(self._value) 

1057 

1058 def __float__(self): 

1059 return float(self._value) 

1060 

1061 def __reversed__(self): 

1062 return reversed(self._value) 

1063 

1064 

1065class Null(OctetString): 

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

1067 

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

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

1070 (always empty). 

1071 

1072 Keyword Args 

1073 ------------ 

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

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

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

1077 

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

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

1080 

1081 Raises 

1082 ------ 

1083 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1084 On constraint violation or bad initializer. 

1085 

1086 Examples 

1087 -------- 

1088 .. code-block:: python 

1089 

1090 class Ack(Null): 

1091 ''' 

1092 ASN.1 specification: 

1093 

1094 Ack ::= NULL 

1095 ''' 

1096 ack = Ack('') 

1097 """ 

1098 

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

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

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

1102 tagSet = tag.initTagSet( 

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

1104 ) 

1105 subtypeSpec = OctetString.subtypeSpec + constraint.SingleValueConstraint(octets.str2octs('')) 

1106 

1107 # Optimization for faster codec lookup 

1108 typeId = OctetString.getTypeId() 

1109 

1110 def prettyIn(self, value): 

1111 if value: 

1112 return value 

1113 

1114 return octets.str2octs('') 

1115 

1116if sys.version_info[0] <= 2: 

1117 intTypes = (int, long) 

1118else: 

1119 intTypes = (int,) 

1120 

1121numericTypes = intTypes + (float,) 

1122 

1123 

1124class ObjectIdentifier(base.SimpleAsn1Type): 

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

1126 

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

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

1129 (tuple of non-negative integers). 

1130 

1131 Keyword Args 

1132 ------------ 

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

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

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

1136 

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

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

1139 

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

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

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

1143 instantiation. 

1144 

1145 Raises 

1146 ------ 

1147 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1148 On constraint violation or bad initializer. 

1149 

1150 Examples 

1151 -------- 

1152 .. code-block:: python 

1153 

1154 class ID(ObjectIdentifier): 

1155 ''' 

1156 ASN.1 specification: 

1157 

1158 ID ::= OBJECT IDENTIFIER 

1159 

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

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

1162 ''' 

1163 id_edims = ID('2.6.7') 

1164 id_bp = id_edims + (11,) 

1165 """ 

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

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

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

1169 tagSet = tag.initTagSet( 

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

1171 ) 

1172 

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

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

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

1176 subtypeSpec = constraint.ConstraintsIntersection() 

1177 

1178 # Optimization for faster codec lookup 

1179 typeId = base.SimpleAsn1Type.getTypeId() 

1180 

1181 def __add__(self, other): 

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

1183 

1184 def __radd__(self, other): 

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

1186 

1187 def asTuple(self): 

1188 return self._value 

1189 

1190 # Sequence object protocol 

1191 

1192 def __len__(self): 

1193 return len(self._value) 

1194 

1195 def __getitem__(self, i): 

1196 if i.__class__ is slice: 

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

1198 else: 

1199 return self._value[i] 

1200 

1201 def __iter__(self): 

1202 return iter(self._value) 

1203 

1204 def __contains__(self, value): 

1205 return value in self._value 

1206 

1207 def index(self, suboid): 

1208 return self._value.index(suboid) 

1209 

1210 def isPrefixOf(self, other): 

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

1212 

1213 Parameters 

1214 ---------- 

1215 other: |ASN.1| object 

1216 |ASN.1| object 

1217 

1218 Returns 

1219 ------- 

1220 : :class:`bool` 

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

1222 or :obj:`False` otherwise. 

1223 """ 

1224 l = len(self) 

1225 if l <= len(other): 

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

1227 return True 

1228 return False 

1229 

1230 def prettyIn(self, value): 

1231 if isinstance(value, ObjectIdentifier): 

1232 return tuple(value) 

1233 elif octets.isStringType(value): 

1234 if '-' in value: 

1235 raise error.PyAsn1Error( 

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

1237 ) 

1238 try: 

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

1240 except ValueError: 

1241 raise error.PyAsn1Error( 

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

1243 ) 

1244 

1245 try: 

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

1247 

1248 except (ValueError, TypeError): 

1249 raise error.PyAsn1Error( 

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

1251 ) 

1252 

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

1254 return tupleOfInts 

1255 

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

1257 

1258 def prettyOut(self, value): 

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

1260 

1261 

1262class Real(base.SimpleAsn1Type): 

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

1264 

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

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

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

1268 elements are mantissa, base and exponent. 

1269 

1270 Keyword Args 

1271 ------------ 

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

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

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

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

1276 

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

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

1279 

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

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

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

1283 instantiation. 

1284 

1285 Raises 

1286 ------ 

1287 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1288 On constraint violation or bad initializer. 

1289 

1290 Examples 

1291 -------- 

1292 .. code-block:: python 

1293 

1294 class Pi(Real): 

1295 ''' 

1296 ASN.1 specification: 

1297 

1298 Pi ::= REAL 

1299 

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

1301 

1302 ''' 

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

1304 """ 

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

1306 

1307 try: 

1308 _plusInf = float('inf') 

1309 _minusInf = float('-inf') 

1310 _inf = _plusInf, _minusInf 

1311 

1312 except ValueError: 

1313 # Infinity support is platform and Python dependent 

1314 _plusInf = _minusInf = None 

1315 _inf = () 

1316 

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

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

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

1320 tagSet = tag.initTagSet( 

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

1322 ) 

1323 

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

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

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

1327 subtypeSpec = constraint.ConstraintsIntersection() 

1328 

1329 # Optimization for faster codec lookup 

1330 typeId = base.SimpleAsn1Type.getTypeId() 

1331 

1332 @staticmethod 

1333 def __normalizeBase10(value): 

1334 m, b, e = value 

1335 while m and m % 10 == 0: 

1336 m /= 10 

1337 e += 1 

1338 return m, b, e 

1339 

1340 def prettyIn(self, value): 

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

1342 if (not isinstance(value[0], numericTypes) or 

1343 not isinstance(value[1], intTypes) or 

1344 not isinstance(value[2], intTypes)): 

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

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

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

1348 return value[0] 

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

1350 raise error.PyAsn1Error( 

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

1352 ) 

1353 if value[1] == 10: 

1354 value = self.__normalizeBase10(value) 

1355 return value 

1356 elif isinstance(value, intTypes): 

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

1358 elif isinstance(value, float) or octets.isStringType(value): 

1359 if octets.isStringType(value): 

1360 try: 

1361 value = float(value) 

1362 except ValueError: 

1363 raise error.PyAsn1Error( 

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

1365 ) 

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

1367 return value 

1368 else: 

1369 e = 0 

1370 while int(value) != value: 

1371 value *= 10 

1372 e -= 1 

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

1374 elif isinstance(value, Real): 

1375 return tuple(value) 

1376 raise error.PyAsn1Error( 

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

1378 ) 

1379 

1380 def prettyPrint(self, scope=0): 

1381 try: 

1382 return self.prettyOut(float(self)) 

1383 

1384 except OverflowError: 

1385 return '<overflow>' 

1386 

1387 @property 

1388 def isPlusInf(self): 

1389 """Indicate PLUS-INFINITY object value 

1390 

1391 Returns 

1392 ------- 

1393 : :class:`bool` 

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

1395 or :obj:`False` otherwise. 

1396 

1397 """ 

1398 return self._value == self._plusInf 

1399 

1400 @property 

1401 def isMinusInf(self): 

1402 """Indicate MINUS-INFINITY object value 

1403 

1404 Returns 

1405 ------- 

1406 : :class:`bool` 

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

1408 or :obj:`False` otherwise. 

1409 """ 

1410 return self._value == self._minusInf 

1411 

1412 @property 

1413 def isInf(self): 

1414 return self._value in self._inf 

1415 

1416 def __add__(self, value): 

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

1418 

1419 def __radd__(self, value): 

1420 return self + value 

1421 

1422 def __mul__(self, value): 

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

1424 

1425 def __rmul__(self, value): 

1426 return self * value 

1427 

1428 def __sub__(self, value): 

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

1430 

1431 def __rsub__(self, value): 

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

1433 

1434 def __mod__(self, value): 

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

1436 

1437 def __rmod__(self, value): 

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

1439 

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

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

1442 

1443 def __rpow__(self, value): 

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

1445 

1446 if sys.version_info[0] <= 2: 

1447 def __div__(self, value): 

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

1449 

1450 def __rdiv__(self, value): 

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

1452 else: 

1453 def __truediv__(self, value): 

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

1455 

1456 def __rtruediv__(self, value): 

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

1458 

1459 def __divmod__(self, value): 

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

1461 

1462 def __rdivmod__(self, value): 

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

1464 

1465 def __int__(self): 

1466 return int(float(self)) 

1467 

1468 if sys.version_info[0] <= 2: 

1469 def __long__(self): 

1470 return long(float(self)) 

1471 

1472 def __float__(self): 

1473 if self._value in self._inf: 

1474 return self._value 

1475 else: 

1476 return float( 

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

1478 ) 

1479 

1480 def __abs__(self): 

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

1482 

1483 def __pos__(self): 

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

1485 

1486 def __neg__(self): 

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

1488 

1489 def __round__(self, n=0): 

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

1491 if n: 

1492 return self.clone(r) 

1493 else: 

1494 return r 

1495 

1496 def __floor__(self): 

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

1498 

1499 def __ceil__(self): 

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

1501 

1502 if sys.version_info[0:2] > (2, 5): 

1503 def __trunc__(self): 

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

1505 

1506 def __lt__(self, value): 

1507 return float(self) < value 

1508 

1509 def __le__(self, value): 

1510 return float(self) <= value 

1511 

1512 def __eq__(self, value): 

1513 return float(self) == value 

1514 

1515 def __ne__(self, value): 

1516 return float(self) != value 

1517 

1518 def __gt__(self, value): 

1519 return float(self) > value 

1520 

1521 def __ge__(self, value): 

1522 return float(self) >= value 

1523 

1524 if sys.version_info[0] <= 2: 

1525 def __nonzero__(self): 

1526 return bool(float(self)) 

1527 else: 

1528 def __bool__(self): 

1529 return bool(float(self)) 

1530 

1531 __hash__ = base.SimpleAsn1Type.__hash__ 

1532 

1533 def __getitem__(self, idx): 

1534 if self._value in self._inf: 

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

1536 else: 

1537 return self._value[idx] 

1538 

1539 # compatibility stubs 

1540 

1541 def isPlusInfinity(self): 

1542 return self.isPlusInf 

1543 

1544 def isMinusInfinity(self): 

1545 return self.isMinusInf 

1546 

1547 def isInfinity(self): 

1548 return self.isInf 

1549 

1550 

1551class Enumerated(Integer): 

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

1553 

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

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

1556 

1557 Keyword Args 

1558 ------------ 

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

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

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

1562 

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

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

1565 

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

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

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

1569 instantiation. 

1570 

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

1572 Object representing non-default symbolic aliases for numbers 

1573 

1574 Raises 

1575 ------ 

1576 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1577 On constraint violation or bad initializer. 

1578 

1579 Examples 

1580 -------- 

1581 

1582 .. code-block:: python 

1583 

1584 class RadioButton(Enumerated): 

1585 ''' 

1586 ASN.1 specification: 

1587 

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

1589 button3(2) } 

1590 

1591 selected-by-default RadioButton ::= button1 

1592 ''' 

1593 namedValues = NamedValues( 

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

1595 ('button3', 2) 

1596 ) 

1597 

1598 selected_by_default = RadioButton('button1') 

1599 """ 

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

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

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

1603 tagSet = tag.initTagSet( 

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

1605 ) 

1606 

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

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

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

1610 subtypeSpec = constraint.ConstraintsIntersection() 

1611 

1612 # Optimization for faster codec lookup 

1613 typeId = Integer.getTypeId() 

1614 

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

1616 #: representing symbolic aliases for numbers 

1617 namedValues = namedval.NamedValues() 

1618 

1619 

1620# "Structured" ASN.1 types 

1621 

1622class SequenceOfAndSetOfBase(base.ConstructedAsn1Type): 

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

1624 

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

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

1627 

1628 Keyword Args 

1629 ------------ 

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

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

1632 

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

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

1635 

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

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

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

1639 `.isInconsistent` call. 

1640 

1641 Examples 

1642 -------- 

1643 

1644 .. code-block:: python 

1645 

1646 class LotteryDraw(SequenceOf): # SetOf is similar 

1647 ''' 

1648 ASN.1 specification: 

1649 

1650 LotteryDraw ::= SEQUENCE OF INTEGER 

1651 ''' 

1652 componentType = Integer() 

1653 

1654 lotteryDraw = LotteryDraw() 

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

1656 """ 

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

1658 # support positional params for backward compatibility 

1659 if args: 

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

1661 'subtypeSpec'), args): 

1662 if key in kwargs: 

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

1664 kwargs['componentType'] = value 

1665 

1666 self._componentValues = noValue 

1667 

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

1669 

1670 # Python list protocol 

1671 

1672 def __getitem__(self, idx): 

1673 try: 

1674 return self.getComponentByPosition(idx) 

1675 

1676 except error.PyAsn1Error: 

1677 raise IndexError(sys.exc_info()[1]) 

1678 

1679 def __setitem__(self, idx, value): 

1680 try: 

1681 self.setComponentByPosition(idx, value) 

1682 

1683 except error.PyAsn1Error: 

1684 raise IndexError(sys.exc_info()[1]) 

1685 

1686 def append(self, value): 

1687 if self._componentValues is noValue: 

1688 pos = 0 

1689 

1690 else: 

1691 pos = len(self._componentValues) 

1692 

1693 self[pos] = value 

1694 

1695 def count(self, value): 

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

1697 

1698 def extend(self, values): 

1699 for value in values: 

1700 self.append(value) 

1701 

1702 if self._componentValues is noValue: 

1703 self._componentValues = {} 

1704 

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

1706 if stop is None: 

1707 stop = len(self) 

1708 

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

1710 

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

1712 values = list(values) 

1713 

1714 try: 

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

1716 

1717 except error.PyAsn1Error: 

1718 raise ValueError(sys.exc_info()[1]) 

1719 

1720 def reverse(self): 

1721 self._componentValues.reverse() 

1722 

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

1724 self._componentValues = dict( 

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

1726 key=key, reverse=reverse))) 

1727 

1728 def __len__(self): 

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

1730 return 0 

1731 

1732 return max(self._componentValues) + 1 

1733 

1734 def __iter__(self): 

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

1736 yield self.getComponentByPosition(idx) 

1737 

1738 def _cloneComponentValues(self, myClone, cloneValueFlag): 

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

1740 if componentValue is not noValue: 

1741 if isinstance(componentValue, base.ConstructedAsn1Type): 

1742 myClone.setComponentByPosition( 

1743 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

1744 ) 

1745 else: 

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

1747 

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

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

1750 

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

1752 

1753 Parameters 

1754 ---------- 

1755 idx : :class:`int` 

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

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

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

1759 sequence. 

1760 

1761 Keyword Args 

1762 ------------ 

1763 default: :class:`object` 

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

1765 object instead of the requested component. 

1766 

1767 instantiate: :class:`bool` 

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

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

1770 returned. 

1771 

1772 Returns 

1773 ------- 

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

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

1776 

1777 Examples 

1778 -------- 

1779 

1780 .. code-block:: python 

1781 

1782 # can also be SetOf 

1783 class MySequenceOf(SequenceOf): 

1784 componentType = OctetString() 

1785 

1786 s = MySequenceOf() 

1787 

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

1789 s.getComponentByPosition(0) 

1790 

1791 # returns None 

1792 s.getComponentByPosition(0, default=None) 

1793 

1794 s.clear() 

1795 

1796 # returns noValue 

1797 s.getComponentByPosition(0, instantiate=False) 

1798 

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

1800 # object and returns it 

1801 s.getComponentByPosition(0, instantiate=True) 

1802 

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

1804 s.setComponentByPosition(0, 'ABCD') 

1805 

1806 # returns OctetString('ABCD') value object 

1807 s.getComponentByPosition(0, instantiate=False) 

1808 

1809 s.clear() 

1810 

1811 # returns noValue 

1812 s.getComponentByPosition(0, instantiate=False) 

1813 """ 

1814 if isinstance(idx, slice): 

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

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

1817 for subidx in indices[idx]] 

1818 

1819 if idx < 0: 

1820 idx = len(self) + idx 

1821 if idx < 0: 

1822 raise error.PyAsn1Error( 

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

1824 

1825 try: 

1826 componentValue = self._componentValues[idx] 

1827 

1828 except (KeyError, error.PyAsn1Error): 

1829 if not instantiate: 

1830 return default 

1831 

1832 self.setComponentByPosition(idx) 

1833 

1834 componentValue = self._componentValues[idx] 

1835 

1836 if default is noValue or componentValue.isValue: 

1837 return componentValue 

1838 else: 

1839 return default 

1840 

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

1842 verifyConstraints=True, 

1843 matchTags=True, 

1844 matchConstraints=True): 

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

1846 

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

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

1849 

1850 Parameters 

1851 ---------- 

1852 idx: :class:`int` 

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

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

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

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

1857 

1858 Keyword Args 

1859 ------------ 

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

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

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

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

1864 

1865 verifyConstraints: :class:`bool` 

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

1867 

1868 matchTags: :class:`bool` 

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

1870 

1871 matchConstraints: :class:`bool` 

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

1873 

1874 Returns 

1875 ------- 

1876 self 

1877 

1878 Raises 

1879 ------ 

1880 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1881 On constraint violation or bad initializer 

1882 IndexError 

1883 When idx > len(self) 

1884 """ 

1885 if isinstance(idx, slice): 

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

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

1888 for subIdx, subValue in enumerate(value): 

1889 self.setComponentByPosition( 

1890 startIdx + subIdx, subValue, verifyConstraints, 

1891 matchTags, matchConstraints) 

1892 return self 

1893 

1894 if idx < 0: 

1895 idx = len(self) + idx 

1896 if idx < 0: 

1897 raise error.PyAsn1Error( 

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

1899 

1900 componentType = self.componentType 

1901 

1902 if self._componentValues is noValue: 

1903 componentValues = {} 

1904 

1905 else: 

1906 componentValues = self._componentValues 

1907 

1908 currentValue = componentValues.get(idx, noValue) 

1909 

1910 if value is noValue: 

1911 if componentType is not None: 

1912 value = componentType.clone() 

1913 

1914 elif currentValue is noValue: 

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

1916 

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

1918 if (componentType is not None and 

1919 isinstance(componentType, base.SimpleAsn1Type)): 

1920 value = componentType.clone(value=value) 

1921 

1922 elif (currentValue is not noValue and 

1923 isinstance(currentValue, base.SimpleAsn1Type)): 

1924 value = currentValue.clone(value=value) 

1925 

1926 else: 

1927 raise error.PyAsn1Error( 

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

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

1930 

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

1932 subtypeChecker = ( 

1933 self.strictConstraints and 

1934 componentType.isSameTypeWith or 

1935 componentType.isSuperTypeOf) 

1936 

1937 if not subtypeChecker(value, verifyConstraints and matchTags, 

1938 verifyConstraints and matchConstraints): 

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

1940 # additional properties associated with componentType 

1941 if componentType.typeId != Any.typeId: 

1942 raise error.PyAsn1Error( 

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

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

1945 

1946 componentValues[idx] = value 

1947 

1948 self._componentValues = componentValues 

1949 

1950 return self 

1951 

1952 @property 

1953 def componentTagMap(self): 

1954 if self.componentType is not None: 

1955 return self.componentType.tagMap 

1956 

1957 @property 

1958 def components(self): 

1959 return [self._componentValues[idx] 

1960 for idx in sorted(self._componentValues)] 

1961 

1962 def clear(self): 

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

1964 

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

1966 built-in. 

1967 """ 

1968 self._componentValues = {} 

1969 return self 

1970 

1971 def reset(self): 

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

1973 

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

1975 distinction between value and schema objects. 

1976 """ 

1977 self._componentValues = noValue 

1978 return self 

1979 

1980 def prettyPrint(self, scope=0): 

1981 scope += 1 

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

1983 

1984 if not self.isValue: 

1985 return representation 

1986 

1987 for idx, componentValue in enumerate(self): 

1988 representation += ' ' * scope 

1989 if (componentValue is noValue and 

1990 self.componentType is not None): 

1991 representation += '<empty>' 

1992 else: 

1993 representation += componentValue.prettyPrint(scope) 

1994 

1995 return representation 

1996 

1997 def prettyPrintType(self, scope=0): 

1998 scope += 1 

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

2000 if self.componentType is not None: 

2001 representation += ' ' * scope 

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

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

2004 

2005 

2006 @property 

2007 def isValue(self): 

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

2009 

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

2011 

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

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

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

2015 

2016 Returns 

2017 ------- 

2018 : :class:`bool` 

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

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

2021 

2022 Note 

2023 ---- 

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

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

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

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

2028 encoding/decoding serialised ASN.1 contents. 

2029 

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

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

2032 """ 

2033 if self._componentValues is noValue: 

2034 return False 

2035 

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

2037 return False 

2038 

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

2040 if componentValue is noValue or not componentValue.isValue: 

2041 return False 

2042 

2043 return True 

2044 

2045 @property 

2046 def isInconsistent(self): 

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

2048 

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

2050 by `subtypeSpec`. 

2051 

2052 Raises 

2053 ------ 

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

2055 """ 

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

2057 return False 

2058 

2059 if self._componentValues is noValue: 

2060 return True 

2061 

2062 mapping = {} 

2063 

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

2065 # Absent fields are not in the mapping 

2066 if value is noValue: 

2067 continue 

2068 

2069 mapping[idx] = value 

2070 

2071 try: 

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

2073 self.subtypeSpec(mapping) 

2074 

2075 except error.PyAsn1Error: 

2076 exc = sys.exc_info()[1] 

2077 return exc 

2078 

2079 return False 

2080 

2081class SequenceOf(SequenceOfAndSetOfBase): 

2082 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2083 

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

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

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

2087 tagSet = tag.initTagSet( 

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

2089 ) 

2090 

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

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

2093 componentType = None 

2094 

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

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

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

2098 subtypeSpec = constraint.ConstraintsIntersection() 

2099 

2100 # Disambiguation ASN.1 types identification 

2101 typeId = SequenceOfAndSetOfBase.getTypeId() 

2102 

2103 

2104class SetOf(SequenceOfAndSetOfBase): 

2105 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2106 

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

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

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

2110 tagSet = tag.initTagSet( 

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

2112 ) 

2113 

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

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

2116 componentType = None 

2117 

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

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

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

2121 subtypeSpec = constraint.ConstraintsIntersection() 

2122 

2123 # Disambiguation ASN.1 types identification 

2124 typeId = SequenceOfAndSetOfBase.getTypeId() 

2125 

2126 

2127class SequenceAndSetBase(base.ConstructedAsn1Type): 

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

2129 

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

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

2132 

2133 Keyword Args 

2134 ------------ 

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

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

2137 

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

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

2140 

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

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

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

2144 `.isInconsistent` call. 

2145 

2146 Examples 

2147 -------- 

2148 

2149 .. code-block:: python 

2150 

2151 class Description(Sequence): # Set is similar 

2152 ''' 

2153 ASN.1 specification: 

2154 

2155 Description ::= SEQUENCE { 

2156 surname IA5String, 

2157 first-name IA5String OPTIONAL, 

2158 age INTEGER DEFAULT 40 

2159 } 

2160 ''' 

2161 componentType = NamedTypes( 

2162 NamedType('surname', IA5String()), 

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

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

2165 ) 

2166 

2167 descr = Description() 

2168 descr['surname'] = 'Smith' 

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

2170 """ 

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

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

2173 componentType = namedtype.NamedTypes() 

2174 

2175 

2176 class DynamicNames(object): 

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

2178 def __init__(self): 

2179 self._keyToIdxMap = {} 

2180 self._idxToKeyMap = {} 

2181 

2182 def __len__(self): 

2183 return len(self._keyToIdxMap) 

2184 

2185 def __contains__(self, item): 

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

2187 

2188 def __iter__(self): 

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

2190 

2191 def __getitem__(self, item): 

2192 try: 

2193 return self._keyToIdxMap[item] 

2194 

2195 except KeyError: 

2196 return self._idxToKeyMap[item] 

2197 

2198 def getNameByPosition(self, idx): 

2199 try: 

2200 return self._idxToKeyMap[idx] 

2201 

2202 except KeyError: 

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

2204 

2205 def getPositionByName(self, name): 

2206 try: 

2207 return self._keyToIdxMap[name] 

2208 

2209 except KeyError: 

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

2211 

2212 def addField(self, idx): 

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

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

2215 

2216 

2217 def __init__(self, **kwargs): 

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

2219 self._componentTypeLen = len(self.componentType) 

2220 if self._componentTypeLen: 

2221 self._componentValues = [] 

2222 else: 

2223 self._componentValues = noValue 

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

2225 

2226 def __getitem__(self, idx): 

2227 if octets.isStringType(idx): 

2228 try: 

2229 return self.getComponentByName(idx) 

2230 

2231 except error.PyAsn1Error: 

2232 # duck-typing dict 

2233 raise KeyError(sys.exc_info()[1]) 

2234 

2235 else: 

2236 try: 

2237 return self.getComponentByPosition(idx) 

2238 

2239 except error.PyAsn1Error: 

2240 # duck-typing list 

2241 raise IndexError(sys.exc_info()[1]) 

2242 

2243 def __setitem__(self, idx, value): 

2244 if octets.isStringType(idx): 

2245 try: 

2246 self.setComponentByName(idx, value) 

2247 

2248 except error.PyAsn1Error: 

2249 # duck-typing dict 

2250 raise KeyError(sys.exc_info()[1]) 

2251 

2252 else: 

2253 try: 

2254 self.setComponentByPosition(idx, value) 

2255 

2256 except error.PyAsn1Error: 

2257 # duck-typing list 

2258 raise IndexError(sys.exc_info()[1]) 

2259 

2260 def __contains__(self, key): 

2261 if self._componentTypeLen: 

2262 return key in self.componentType 

2263 else: 

2264 return key in self._dynamicNames 

2265 

2266 def __len__(self): 

2267 return len(self._componentValues) 

2268 

2269 def __iter__(self): 

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

2271 

2272 # Python dict protocol 

2273 

2274 def values(self): 

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

2276 yield self[idx] 

2277 

2278 def keys(self): 

2279 return iter(self) 

2280 

2281 def items(self): 

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

2283 if self._componentTypeLen: 

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

2285 else: 

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

2287 

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

2289 for k, v in iterValue: 

2290 self[k] = v 

2291 for k in mappingValue: 

2292 self[k] = mappingValue[k] 

2293 

2294 def clear(self): 

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

2296 

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

2298 built-in. 

2299 """ 

2300 self._componentValues = [] 

2301 self._dynamicNames = self.DynamicNames() 

2302 return self 

2303 

2304 def reset(self): 

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

2306 

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

2308 distinction between value and schema objects. 

2309 """ 

2310 self._componentValues = noValue 

2311 self._dynamicNames = self.DynamicNames() 

2312 return self 

2313 

2314 @property 

2315 def components(self): 

2316 return self._componentValues 

2317 

2318 def _cloneComponentValues(self, myClone, cloneValueFlag): 

2319 if self._componentValues is noValue: 

2320 return 

2321 

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

2323 if componentValue is not noValue: 

2324 if isinstance(componentValue, base.ConstructedAsn1Type): 

2325 myClone.setComponentByPosition( 

2326 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

2327 ) 

2328 else: 

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

2330 

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

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

2333 

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

2335 

2336 Parameters 

2337 ---------- 

2338 name: :class:`str` 

2339 |ASN.1| type component name 

2340 

2341 Keyword Args 

2342 ------------ 

2343 default: :class:`object` 

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

2345 object instead of the requested component. 

2346 

2347 instantiate: :class:`bool` 

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

2349 instantiated. 

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

2351 object will be returned. 

2352 

2353 Returns 

2354 ------- 

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

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

2357 component value 

2358 """ 

2359 if self._componentTypeLen: 

2360 idx = self.componentType.getPositionByName(name) 

2361 else: 

2362 try: 

2363 idx = self._dynamicNames.getPositionByName(name) 

2364 

2365 except KeyError: 

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

2367 

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

2369 

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

2371 verifyConstraints=True, 

2372 matchTags=True, 

2373 matchConstraints=True): 

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

2375 

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

2377 

2378 Parameters 

2379 ---------- 

2380 name: :class:`str` 

2381 |ASN.1| type component name 

2382 

2383 Keyword Args 

2384 ------------ 

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

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

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

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

2389 

2390 verifyConstraints: :class:`bool` 

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

2392 

2393 matchTags: :class:`bool` 

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

2395 

2396 matchConstraints: :class:`bool` 

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

2398 

2399 Returns 

2400 ------- 

2401 self 

2402 """ 

2403 if self._componentTypeLen: 

2404 idx = self.componentType.getPositionByName(name) 

2405 else: 

2406 try: 

2407 idx = self._dynamicNames.getPositionByName(name) 

2408 

2409 except KeyError: 

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

2411 

2412 return self.setComponentByPosition( 

2413 idx, value, verifyConstraints, matchTags, matchConstraints 

2414 ) 

2415 

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

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

2418 

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

2420 

2421 Parameters 

2422 ---------- 

2423 idx: :class:`int` 

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

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

2426 instantiated. 

2427 

2428 Keyword Args 

2429 ------------ 

2430 default: :class:`object` 

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

2432 object instead of the requested component. 

2433 

2434 instantiate: :class:`bool` 

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

2436 instantiated. 

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

2438 object will be returned. 

2439 

2440 Returns 

2441 ------- 

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

2443 a PyASN1 object 

2444 

2445 Examples 

2446 -------- 

2447 

2448 .. code-block:: python 

2449 

2450 # can also be Set 

2451 class MySequence(Sequence): 

2452 componentType = NamedTypes( 

2453 NamedType('id', OctetString()) 

2454 ) 

2455 

2456 s = MySequence() 

2457 

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

2459 s.getComponentByPosition(0) 

2460 

2461 # returns None 

2462 s.getComponentByPosition(0, default=None) 

2463 

2464 s.clear() 

2465 

2466 # returns noValue 

2467 s.getComponentByPosition(0, instantiate=False) 

2468 

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

2470 # object and returns it 

2471 s.getComponentByPosition(0, instantiate=True) 

2472 

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

2474 s.setComponentByPosition(0, 'ABCD') 

2475 

2476 # returns OctetString('ABCD') value object 

2477 s.getComponentByPosition(0, instantiate=False) 

2478 

2479 s.clear() 

2480 

2481 # returns noValue 

2482 s.getComponentByPosition(0, instantiate=False) 

2483 """ 

2484 try: 

2485 if self._componentValues is noValue: 

2486 componentValue = noValue 

2487 

2488 else: 

2489 componentValue = self._componentValues[idx] 

2490 

2491 except IndexError: 

2492 componentValue = noValue 

2493 

2494 if not instantiate: 

2495 if componentValue is noValue or not componentValue.isValue: 

2496 return default 

2497 else: 

2498 return componentValue 

2499 

2500 if componentValue is noValue: 

2501 self.setComponentByPosition(idx) 

2502 

2503 componentValue = self._componentValues[idx] 

2504 

2505 if default is noValue or componentValue.isValue: 

2506 return componentValue 

2507 else: 

2508 return default 

2509 

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

2511 verifyConstraints=True, 

2512 matchTags=True, 

2513 matchConstraints=True): 

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

2515 

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

2517 

2518 Parameters 

2519 ---------- 

2520 idx : :class:`int` 

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

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

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

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

2525 

2526 Keyword Args 

2527 ------------ 

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

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

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

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

2532 

2533 verifyConstraints : :class:`bool` 

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

2535 

2536 matchTags: :class:`bool` 

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

2538 

2539 matchConstraints: :class:`bool` 

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

2541 

2542 Returns 

2543 ------- 

2544 self 

2545 """ 

2546 componentType = self.componentType 

2547 componentTypeLen = self._componentTypeLen 

2548 

2549 if self._componentValues is noValue: 

2550 componentValues = [] 

2551 

2552 else: 

2553 componentValues = self._componentValues 

2554 

2555 try: 

2556 currentValue = componentValues[idx] 

2557 

2558 except IndexError: 

2559 currentValue = noValue 

2560 if componentTypeLen: 

2561 if componentTypeLen < idx: 

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

2563 

2564 componentValues = [noValue] * componentTypeLen 

2565 

2566 if value is noValue: 

2567 if componentTypeLen: 

2568 value = componentType.getTypeByPosition(idx) 

2569 if isinstance(value, base.ConstructedAsn1Type): 

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

2571 

2572 elif currentValue is noValue: 

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

2574 

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

2576 if componentTypeLen: 

2577 subComponentType = componentType.getTypeByPosition(idx) 

2578 if isinstance(subComponentType, base.SimpleAsn1Type): 

2579 value = subComponentType.clone(value=value) 

2580 

2581 else: 

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

2583 

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

2585 value = currentValue.clone(value=value) 

2586 

2587 else: 

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

2589 

2590 elif ((verifyConstraints or matchTags or matchConstraints) and 

2591 componentTypeLen): 

2592 subComponentType = componentType.getTypeByPosition(idx) 

2593 if subComponentType is not noValue: 

2594 subtypeChecker = (self.strictConstraints and 

2595 subComponentType.isSameTypeWith or 

2596 subComponentType.isSuperTypeOf) 

2597 

2598 if not subtypeChecker(value, verifyConstraints and matchTags, 

2599 verifyConstraints and matchConstraints): 

2600 if not componentType[idx].openType: 

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

2602 

2603 if componentTypeLen or idx in self._dynamicNames: 

2604 componentValues[idx] = value 

2605 

2606 elif len(componentValues) == idx: 

2607 componentValues.append(value) 

2608 self._dynamicNames.addField(idx) 

2609 

2610 else: 

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

2612 

2613 self._componentValues = componentValues 

2614 

2615 return self 

2616 

2617 @property 

2618 def isValue(self): 

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

2620 

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

2622 

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

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

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

2626 

2627 Returns 

2628 ------- 

2629 : :class:`bool` 

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

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

2632 normal value. 

2633 

2634 Note 

2635 ---- 

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

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

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

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

2640 encoding/decoding serialised ASN.1 contents. 

2641 

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

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

2644 

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

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

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

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

2649 components are normally value objects by default. 

2650 """ 

2651 if self._componentValues is noValue: 

2652 return False 

2653 

2654 componentType = self.componentType 

2655 

2656 if componentType: 

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

2658 if subComponentType.isDefaulted or subComponentType.isOptional: 

2659 continue 

2660 

2661 if not self._componentValues: 

2662 return False 

2663 

2664 componentValue = self._componentValues[idx] 

2665 if componentValue is noValue or not componentValue.isValue: 

2666 return False 

2667 

2668 else: 

2669 for componentValue in self._componentValues: 

2670 if componentValue is noValue or not componentValue.isValue: 

2671 return False 

2672 

2673 return True 

2674 

2675 @property 

2676 def isInconsistent(self): 

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

2678 

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

2680 by `subtypeSpec`. 

2681 

2682 Raises 

2683 ------ 

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

2685 """ 

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

2687 return False 

2688 

2689 if self._componentValues is noValue: 

2690 return True 

2691 

2692 mapping = {} 

2693 

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

2695 # Absent fields are not in the mapping 

2696 if value is noValue: 

2697 continue 

2698 

2699 name = self.componentType.getNameByPosition(idx) 

2700 

2701 mapping[name] = value 

2702 

2703 try: 

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

2705 self.subtypeSpec(mapping) 

2706 

2707 except error.PyAsn1Error: 

2708 exc = sys.exc_info()[1] 

2709 return exc 

2710 

2711 return False 

2712 

2713 def prettyPrint(self, scope=0): 

2714 """Return an object representation string. 

2715 

2716 Returns 

2717 ------- 

2718 : :class:`str` 

2719 Human-friendly object representation. 

2720 """ 

2721 scope += 1 

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

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

2724 if componentValue is not noValue and componentValue.isValue: 

2725 representation += ' ' * scope 

2726 if self.componentType: 

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

2728 else: 

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

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

2731 representation, componentValue.prettyPrint(scope) 

2732 ) 

2733 return representation 

2734 

2735 def prettyPrintType(self, scope=0): 

2736 scope += 1 

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

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

2739 representation += ' ' * scope 

2740 if self.componentType: 

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

2742 else: 

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

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

2745 representation, componentType.prettyPrintType(scope) 

2746 ) 

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

2748 

2749 # backward compatibility 

2750 

2751 def setDefaultComponents(self): 

2752 return self 

2753 

2754 def getComponentType(self): 

2755 if self._componentTypeLen: 

2756 return self.componentType 

2757 

2758 def getNameByPosition(self, idx): 

2759 if self._componentTypeLen: 

2760 return self.componentType[idx].name 

2761 

2762class Sequence(SequenceAndSetBase): 

2763 __doc__ = SequenceAndSetBase.__doc__ 

2764 

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

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

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

2768 tagSet = tag.initTagSet( 

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

2770 ) 

2771 

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

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

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

2775 subtypeSpec = constraint.ConstraintsIntersection() 

2776 

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

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

2779 componentType = namedtype.NamedTypes() 

2780 

2781 # Disambiguation ASN.1 types identification 

2782 typeId = SequenceAndSetBase.getTypeId() 

2783 

2784 # backward compatibility 

2785 

2786 def getComponentTagMapNearPosition(self, idx): 

2787 if self.componentType: 

2788 return self.componentType.getTagMapNearPosition(idx) 

2789 

2790 def getComponentPositionNearType(self, tagSet, idx): 

2791 if self.componentType: 

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

2793 else: 

2794 return idx 

2795 

2796 

2797class Set(SequenceAndSetBase): 

2798 __doc__ = SequenceAndSetBase.__doc__ 

2799 

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

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

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

2803 tagSet = tag.initTagSet( 

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

2805 ) 

2806 

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

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

2809 componentType = namedtype.NamedTypes() 

2810 

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

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

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

2814 subtypeSpec = constraint.ConstraintsIntersection() 

2815 

2816 # Disambiguation ASN.1 types identification 

2817 typeId = SequenceAndSetBase.getTypeId() 

2818 

2819 def getComponent(self, innerFlag=False): 

2820 return self 

2821 

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

2823 instantiate=True, innerFlag=False): 

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

2825 

2826 Parameters 

2827 ---------- 

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

2829 Object representing ASN.1 tags to identify one of 

2830 |ASN.1| object component 

2831 

2832 Keyword Args 

2833 ------------ 

2834 default: :class:`object` 

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

2836 object instead of the requested component. 

2837 

2838 instantiate: :class:`bool` 

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

2840 instantiated. 

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

2842 object will be returned. 

2843 

2844 Returns 

2845 ------- 

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

2847 a pyasn1 object 

2848 """ 

2849 componentValue = self.getComponentByPosition( 

2850 self.componentType.getPositionByType(tagSet), 

2851 default=default, instantiate=instantiate 

2852 ) 

2853 if innerFlag and isinstance(componentValue, Set): 

2854 # get inner component by inner tagSet 

2855 return componentValue.getComponent(innerFlag=True) 

2856 else: 

2857 # get outer component by inner tagSet 

2858 return componentValue 

2859 

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

2861 verifyConstraints=True, 

2862 matchTags=True, 

2863 matchConstraints=True, 

2864 innerFlag=False): 

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

2866 

2867 Parameters 

2868 ---------- 

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

2870 Object representing ASN.1 tags to identify one of 

2871 |ASN.1| object component 

2872 

2873 Keyword Args 

2874 ------------ 

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

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

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

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

2879 

2880 verifyConstraints : :class:`bool` 

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

2882 

2883 matchTags: :class:`bool` 

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

2885 

2886 matchConstraints: :class:`bool` 

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

2888 

2889 innerFlag: :class:`bool` 

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

2891 

2892 Returns 

2893 ------- 

2894 self 

2895 """ 

2896 idx = self.componentType.getPositionByType(tagSet) 

2897 

2898 if innerFlag: # set inner component by inner tagSet 

2899 componentType = self.componentType.getTypeByPosition(idx) 

2900 

2901 if componentType.tagSet: 

2902 return self.setComponentByPosition( 

2903 idx, value, verifyConstraints, matchTags, matchConstraints 

2904 ) 

2905 else: 

2906 componentType = self.getComponentByPosition(idx) 

2907 return componentType.setComponentByType( 

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

2909 ) 

2910 else: # set outer component by inner tagSet 

2911 return self.setComponentByPosition( 

2912 idx, value, verifyConstraints, matchTags, matchConstraints 

2913 ) 

2914 

2915 @property 

2916 def componentTagMap(self): 

2917 if self.componentType: 

2918 return self.componentType.tagMapUnique 

2919 

2920 

2921class Choice(Set): 

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

2923 

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

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

2926 

2927 Keyword Args 

2928 ------------ 

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

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

2931 

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

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

2934 

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

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

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

2938 `.isInconsistent` call. 

2939 

2940 Examples 

2941 -------- 

2942 

2943 .. code-block:: python 

2944 

2945 class Afters(Choice): 

2946 ''' 

2947 ASN.1 specification: 

2948 

2949 Afters ::= CHOICE { 

2950 cheese [0] IA5String, 

2951 dessert [1] IA5String 

2952 } 

2953 ''' 

2954 componentType = NamedTypes( 

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

2956 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 

2957 ), 

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

2959 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 

2960 ) 

2961 ) 

2962 

2963 afters = Afters() 

2964 afters['cheese'] = 'Mascarpone' 

2965 """ 

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

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

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

2969 tagSet = tag.TagSet() # untagged 

2970 

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

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

2973 componentType = namedtype.NamedTypes() 

2974 

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

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

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

2978 subtypeSpec = constraint.ConstraintsIntersection( 

2979 constraint.ValueSizeConstraint(1, 1) 

2980 ) 

2981 

2982 # Disambiguation ASN.1 types identification 

2983 typeId = Set.getTypeId() 

2984 

2985 _currentIdx = None 

2986 

2987 def __eq__(self, other): 

2988 if self._componentValues: 

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

2990 return NotImplemented 

2991 

2992 def __ne__(self, other): 

2993 if self._componentValues: 

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

2995 return NotImplemented 

2996 

2997 def __lt__(self, other): 

2998 if self._componentValues: 

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

3000 return NotImplemented 

3001 

3002 def __le__(self, other): 

3003 if self._componentValues: 

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

3005 return NotImplemented 

3006 

3007 def __gt__(self, other): 

3008 if self._componentValues: 

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

3010 return NotImplemented 

3011 

3012 def __ge__(self, other): 

3013 if self._componentValues: 

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

3015 return NotImplemented 

3016 

3017 if sys.version_info[0] <= 2: 

3018 def __nonzero__(self): 

3019 return self._componentValues and True or False 

3020 else: 

3021 def __bool__(self): 

3022 return self._componentValues and True or False 

3023 

3024 def __len__(self): 

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

3026 

3027 def __contains__(self, key): 

3028 if self._currentIdx is None: 

3029 return False 

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

3031 

3032 def __iter__(self): 

3033 if self._currentIdx is None: 

3034 raise StopIteration 

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

3036 

3037 # Python dict protocol 

3038 

3039 def values(self): 

3040 if self._currentIdx is not None: 

3041 yield self._componentValues[self._currentIdx] 

3042 

3043 def keys(self): 

3044 if self._currentIdx is not None: 

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

3046 

3047 def items(self): 

3048 if self._currentIdx is not None: 

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

3050 

3051 def checkConsistency(self): 

3052 if self._currentIdx is None: 

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

3054 

3055 def _cloneComponentValues(self, myClone, cloneValueFlag): 

3056 try: 

3057 component = self.getComponent() 

3058 except error.PyAsn1Error: 

3059 pass 

3060 else: 

3061 if isinstance(component, Choice): 

3062 tagSet = component.effectiveTagSet 

3063 else: 

3064 tagSet = component.tagSet 

3065 if isinstance(component, base.ConstructedAsn1Type): 

3066 myClone.setComponentByType( 

3067 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 

3068 ) 

3069 else: 

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

3071 

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

3073 __doc__ = Set.__doc__ 

3074 

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

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

3077 instantiate=instantiate) 

3078 

3079 return self._componentValues[idx] 

3080 

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

3082 verifyConstraints=True, 

3083 matchTags=True, 

3084 matchConstraints=True): 

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

3086 

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

3088 

3089 Parameters 

3090 ---------- 

3091 idx: :class:`int` 

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

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

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

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

3096 

3097 Keyword Args 

3098 ------------ 

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

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

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

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

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

3104 

3105 verifyConstraints : :class:`bool` 

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

3107 

3108 matchTags: :class:`bool` 

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

3110 

3111 matchConstraints: :class:`bool` 

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

3113 

3114 Returns 

3115 ------- 

3116 self 

3117 """ 

3118 oldIdx = self._currentIdx 

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

3120 self._currentIdx = idx 

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

3122 self._componentValues[oldIdx] = noValue 

3123 return self 

3124 

3125 @property 

3126 def effectiveTagSet(self): 

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

3128 if self.tagSet: 

3129 return self.tagSet 

3130 else: 

3131 component = self.getComponent() 

3132 return component.effectiveTagSet 

3133 

3134 @property 

3135 def tagMap(self): 

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

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

3138 """ 

3139 if self.tagSet: 

3140 return Set.tagMap.fget(self) 

3141 else: 

3142 return self.componentType.tagMapUnique 

3143 

3144 def getComponent(self, innerFlag=False): 

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

3146 

3147 Returns 

3148 ------- 

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

3150 a PyASN1 object 

3151 """ 

3152 if self._currentIdx is None: 

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

3154 else: 

3155 c = self._componentValues[self._currentIdx] 

3156 if innerFlag and isinstance(c, Choice): 

3157 return c.getComponent(innerFlag) 

3158 else: 

3159 return c 

3160 

3161 def getName(self, innerFlag=False): 

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

3163 

3164 Returns 

3165 ------- 

3166 : :py:class:`str` 

3167 |ASN.1| component name 

3168 """ 

3169 if self._currentIdx is None: 

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

3171 else: 

3172 if innerFlag: 

3173 c = self._componentValues[self._currentIdx] 

3174 if isinstance(c, Choice): 

3175 return c.getName(innerFlag) 

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

3177 

3178 @property 

3179 def isValue(self): 

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

3181 

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

3183 

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

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

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

3187 

3188 Returns 

3189 ------- 

3190 : :class:`bool` 

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

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

3193 value. 

3194 

3195 Note 

3196 ---- 

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

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

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

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

3201 encoding/decoding serialised ASN.1 contents. 

3202 

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

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

3205 """ 

3206 if self._currentIdx is None: 

3207 return False 

3208 

3209 componentValue = self._componentValues[self._currentIdx] 

3210 

3211 return componentValue is not noValue and componentValue.isValue 

3212 

3213 def clear(self): 

3214 self._currentIdx = None 

3215 return Set.clear(self) 

3216 

3217 # compatibility stubs 

3218 

3219 def getMinTagSet(self): 

3220 return self.minTagSet 

3221 

3222 

3223class Any(OctetString): 

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

3225 

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

3227 its objects are immutable and duck-type Python 2 :class:`str` or Python 3 

3228 :class:`bytes`. When used in Unicode context, |ASN.1| type assumes 

3229 "|encoding|" serialisation. 

3230 

3231 Keyword Args 

3232 ------------ 

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

3234 :class:`str` (Python 2) or :class:`bytes` (Python 3), alternatively 

3235 :class:`unicode` object (Python 2) or :class:`str` (Python 3) 

3236 representing character string to be serialised into octets (note 

3237 `encoding` parameter) or |ASN.1| object. 

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

3239 

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

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

3242 

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

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

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

3246 instantiation. 

3247 

3248 encoding: :py:class:`str` 

3249 Unicode codec ID to encode/decode :class:`unicode` (Python 2) or 

3250 :class:`str` (Python 3) the payload when |ASN.1| object is used 

3251 in text string context. 

3252 

3253 binValue: :py:class:`str` 

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

3255 Example: '10110011'. 

3256 

3257 hexValue: :py:class:`str` 

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

3259 Example: 'DEADBEEF'. 

3260 

3261 Raises 

3262 ------ 

3263 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

3264 On constraint violation or bad initializer. 

3265 

3266 Examples 

3267 -------- 

3268 .. code-block:: python 

3269 

3270 class Error(Sequence): 

3271 ''' 

3272 ASN.1 specification: 

3273 

3274 Error ::= SEQUENCE { 

3275 code INTEGER, 

3276 parameter ANY DEFINED BY code -- Either INTEGER or REAL 

3277 } 

3278 ''' 

3279 componentType=NamedTypes( 

3280 NamedType('code', Integer()), 

3281 NamedType('parameter', Any(), 

3282 openType=OpenType('code', {1: Integer(), 

3283 2: Real()})) 

3284 ) 

3285 

3286 error = Error() 

3287 error['code'] = 1 

3288 error['parameter'] = Integer(1234) 

3289 """ 

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

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

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

3293 tagSet = tag.TagSet() # untagged 

3294 

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

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

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

3298 subtypeSpec = constraint.ConstraintsIntersection() 

3299 

3300 # Disambiguation ASN.1 types identification 

3301 typeId = OctetString.getTypeId() 

3302 

3303 @property 

3304 def tagMap(self): 

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

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

3307 """ 

3308 try: 

3309 return self._tagMap 

3310 

3311 except AttributeError: 

3312 self._tagMap = tagmap.TagMap( 

3313 {self.tagSet: self}, 

3314 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 

3315 self 

3316 ) 

3317 

3318 return self._tagMap 

3319 

3320# XXX 

3321# coercion rules?