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

1263 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

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

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

6# 

7import math 

8import sys 

9 

10from pyasn1 import error 

11from pyasn1.codec.ber import eoo 

12from pyasn1.compat import integer 

13from pyasn1.compat import octets 

14from pyasn1.type import base 

15from pyasn1.type import constraint 

16from pyasn1.type import namedtype 

17from pyasn1.type import namedval 

18from pyasn1.type import tag 

19from pyasn1.type import tagmap 

20 

21NoValue = base.NoValue 

22noValue = NoValue() 

23 

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

25 'ObjectIdentifier', 'Real', 'Enumerated', 

26 'SequenceOfAndSetOfBase', 'SequenceOf', 'SetOf', 

27 'SequenceAndSetBase', 'Sequence', 'Set', 'Choice', 'Any', 

28 'NoValue', 'noValue'] 

29 

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

31 

32 

33class Integer(base.SimpleAsn1Type): 

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

35 

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

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

38 

39 Keyword Args 

40 ------------ 

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

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

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

44 

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

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

47 

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

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

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

51 instantiation. 

52 

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

54 Object representing non-default symbolic aliases for numbers 

55 

56 Raises 

57 ------ 

58 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

59 On constraint violation or bad initializer. 

60 

61 Examples 

62 -------- 

63 

64 .. code-block:: python 

65 

66 class ErrorCode(Integer): 

67 ''' 

68 ASN.1 specification: 

69 

70 ErrorCode ::= 

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

72 disk-not-formatted(2) } 

73 

74 error ErrorCode ::= disk-full 

75 ''' 

76 namedValues = NamedValues( 

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

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

79 ) 

80 

81 error = ErrorCode('disk-full') 

82 """ 

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

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

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

86 tagSet = tag.initTagSet( 

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

88 ) 

89 

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

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

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

93 subtypeSpec = constraint.ConstraintsIntersection() 

94 

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

96 #: representing symbolic aliases for numbers 

97 namedValues = namedval.NamedValues() 

98 

99 # Optimization for faster codec lookup 

100 typeId = base.SimpleAsn1Type.getTypeId() 

101 

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

103 if 'namedValues' not in kwargs: 

104 kwargs['namedValues'] = self.namedValues 

105 

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

107 

108 def __and__(self, value): 

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

110 

111 def __rand__(self, value): 

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

113 

114 def __or__(self, value): 

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

116 

117 def __ror__(self, value): 

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

119 

120 def __xor__(self, value): 

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

122 

123 def __rxor__(self, value): 

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

125 

126 def __lshift__(self, value): 

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

128 

129 def __rshift__(self, value): 

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

131 

132 def __add__(self, value): 

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

134 

135 def __radd__(self, value): 

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

137 

138 def __sub__(self, value): 

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

140 

141 def __rsub__(self, value): 

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

143 

144 def __mul__(self, value): 

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

146 

147 def __rmul__(self, value): 

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

149 

150 def __mod__(self, value): 

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

152 

153 def __rmod__(self, value): 

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

155 

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

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

158 

159 def __rpow__(self, value): 

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

161 

162 def __floordiv__(self, value): 

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

164 

165 def __rfloordiv__(self, value): 

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

167 

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

169 def __div__(self, value): 

170 if isinstance(value, float): 

171 return Real(self._value / value) 

172 else: 

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

174 

175 def __rdiv__(self, value): 

176 if isinstance(value, float): 

177 return Real(value / self._value) 

178 else: 

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

180 else: 

181 def __truediv__(self, value): 

182 return Real(self._value / value) 

183 

184 def __rtruediv__(self, value): 

185 return Real(value / self._value) 

186 

187 def __divmod__(self, value): 

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

189 

190 def __rdivmod__(self, value): 

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

192 

193 __hash__ = base.SimpleAsn1Type.__hash__ 

194 

195 def __int__(self): 

196 return int(self._value) 

197 

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

199 def __long__(self): 

200 return long(self._value) 

201 

202 def __float__(self): 

203 return float(self._value) 

204 

205 def __abs__(self): 

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

207 

208 def __index__(self): 

209 return int(self._value) 

210 

211 def __pos__(self): 

212 return self.clone(+self._value) 

213 

214 def __neg__(self): 

215 return self.clone(-self._value) 

216 

217 def __invert__(self): 

218 return self.clone(~self._value) 

219 

220 def __round__(self, n=0): 

221 r = round(self._value, n) 

222 if n: 

223 return self.clone(r) 

224 else: 

225 return r 

226 

227 def __floor__(self): 

228 return math.floor(self._value) 

229 

230 def __ceil__(self): 

231 return math.ceil(self._value) 

232 

233 def __trunc__(self): 

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

235 

236 def __lt__(self, value): 

237 return self._value < value 

238 

239 def __le__(self, value): 

240 return self._value <= value 

241 

242 def __eq__(self, value): 

243 return self._value == value 

244 

245 def __ne__(self, value): 

246 return self._value != value 

247 

248 def __gt__(self, value): 

249 return self._value > value 

250 

251 def __ge__(self, value): 

252 return self._value >= value 

253 

254 def prettyIn(self, value): 

255 try: 

256 return int(value) 

257 

258 except ValueError: 

259 try: 

260 return self.namedValues[value] 

261 

262 except KeyError: 

263 raise error.PyAsn1Error( 

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

265 ) 

266 

267 def prettyOut(self, value): 

268 try: 

269 return str(self.namedValues[value]) 

270 

271 except KeyError: 

272 return str(value) 

273 

274 # backward compatibility 

275 

276 def getNamedValues(self): 

277 return self.namedValues 

278 

279 

280class Boolean(Integer): 

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

282 

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

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

285 

286 Keyword Args 

287 ------------ 

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

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

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

291 

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

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

294 

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

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

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

298 instantiation. 

299 

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

301 Object representing non-default symbolic aliases for numbers 

302 

303 Raises 

304 ------ 

305 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

306 On constraint violation or bad initializer. 

307 

308 Examples 

309 -------- 

310 .. code-block:: python 

311 

312 class RoundResult(Boolean): 

313 ''' 

314 ASN.1 specification: 

315 

316 RoundResult ::= BOOLEAN 

317 

318 ok RoundResult ::= TRUE 

319 ko RoundResult ::= FALSE 

320 ''' 

321 ok = RoundResult(True) 

322 ko = RoundResult(False) 

323 """ 

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

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

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

327 tagSet = tag.initTagSet( 

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

329 ) 

330 

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

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

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

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

335 

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

337 #: representing symbolic aliases for numbers 

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

339 

340 # Optimization for faster codec lookup 

341 typeId = Integer.getTypeId() 

342 

343if sys.version_info[0] < 3: 

344 SizedIntegerBase = long 

345else: 

346 SizedIntegerBase = int 

347 

348 

349class SizedInteger(SizedIntegerBase): 

350 bitLength = leadingZeroBits = None 

351 

352 def setBitLength(self, bitLength): 

353 self.bitLength = bitLength 

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

355 return self 

356 

357 def __len__(self): 

358 if self.bitLength is None: 

359 self.setBitLength(integer.bitLength(self)) 

360 

361 return self.bitLength 

362 

363 

364class BitString(base.SimpleAsn1Type): 

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

366 

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

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

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

370 

371 Keyword Args 

372 ------------ 

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

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

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

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

377 

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

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

380 

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

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

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

384 instantiation. 

385 

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

387 Object representing non-default symbolic aliases for numbers 

388 

389 binValue: :py:class:`str` 

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

391 Example: '10110011'. 

392 

393 hexValue: :py:class:`str` 

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

395 Example: 'DEADBEEF'. 

396 

397 Raises 

398 ------ 

399 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

400 On constraint violation or bad initializer. 

401 

402 Examples 

403 -------- 

404 .. code-block:: python 

405 

406 class Rights(BitString): 

407 ''' 

408 ASN.1 specification: 

409 

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

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

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

413 

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

415 group2 Rights ::= '0011'B 

416 group3 Rights ::= '3'H 

417 ''' 

418 namedValues = NamedValues( 

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

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

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

422 ) 

423 

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

425 group2 = Rights('0011') 

426 group3 = Rights(0x3) 

427 """ 

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

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

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

431 tagSet = tag.initTagSet( 

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

433 ) 

434 

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

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

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

438 subtypeSpec = constraint.ConstraintsIntersection() 

439 

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

441 #: representing symbolic aliases for numbers 

442 namedValues = namedval.NamedValues() 

443 

444 # Optimization for faster codec lookup 

445 typeId = base.SimpleAsn1Type.getTypeId() 

446 

447 defaultBinValue = defaultHexValue = noValue 

448 

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

450 if value is noValue: 

451 if kwargs: 

452 try: 

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

454 

455 except KeyError: 

456 pass 

457 

458 try: 

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

460 

461 except KeyError: 

462 pass 

463 

464 if value is noValue: 

465 if self.defaultBinValue is not noValue: 

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

467 

468 elif self.defaultHexValue is not noValue: 

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

470 

471 if 'namedValues' not in kwargs: 

472 kwargs['namedValues'] = self.namedValues 

473 

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

475 

476 def __str__(self): 

477 return self.asBinary() 

478 

479 def __eq__(self, other): 

480 other = self.prettyIn(other) 

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

482 

483 def __ne__(self, other): 

484 other = self.prettyIn(other) 

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

486 

487 def __lt__(self, other): 

488 other = self.prettyIn(other) 

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

490 

491 def __le__(self, other): 

492 other = self.prettyIn(other) 

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

494 

495 def __gt__(self, other): 

496 other = self.prettyIn(other) 

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

498 

499 def __ge__(self, other): 

500 other = self.prettyIn(other) 

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

502 

503 # Immutable sequence object protocol 

504 

505 def __len__(self): 

506 return len(self._value) 

507 

508 def __getitem__(self, i): 

509 if i.__class__ is slice: 

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

511 else: 

512 length = len(self._value) - 1 

513 if i > length or i < 0: 

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

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

516 

517 def __iter__(self): 

518 length = len(self._value) 

519 while length: 

520 length -= 1 

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

522 

523 def __reversed__(self): 

524 return reversed(tuple(self)) 

525 

526 # arithmetic operators 

527 

528 def __add__(self, value): 

529 value = self.prettyIn(value) 

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

531 

532 def __radd__(self, value): 

533 value = self.prettyIn(value) 

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

535 

536 def __mul__(self, value): 

537 bitString = self._value 

538 while value > 1: 

539 bitString <<= len(self._value) 

540 bitString |= self._value 

541 value -= 1 

542 return self.clone(bitString) 

543 

544 def __rmul__(self, value): 

545 return self * value 

546 

547 def __lshift__(self, count): 

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

549 

550 def __rshift__(self, count): 

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

552 

553 def __int__(self): 

554 return int(self._value) 

555 

556 def __float__(self): 

557 return float(self._value) 

558 

559 if sys.version_info[0] < 3: 

560 def __long__(self): 

561 return self._value 

562 

563 def asNumbers(self): 

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

565 

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

567 will be left-padded with zeros. 

568 """ 

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

570 

571 def asOctets(self): 

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

573 

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

575 will be left-padded with zeros. 

576 """ 

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

578 

579 def asInteger(self): 

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

581 """ 

582 return self._value 

583 

584 def asBinary(self): 

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

586 """ 

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

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

589 

590 @classmethod 

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

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

593 

594 Parameters 

595 ---------- 

596 value: :class:`str` 

597 Text string like 'DEADBEEF' 

598 """ 

599 try: 

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

601 

602 except ValueError: 

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

604 

605 if prepend is not None: 

606 value = SizedInteger( 

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

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

609 

610 if not internalFormat: 

611 value = cls(value) 

612 

613 return value 

614 

615 @classmethod 

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

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

618 

619 Parameters 

620 ---------- 

621 value: :class:`str` 

622 Text string like '1010111' 

623 """ 

624 try: 

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

626 

627 except ValueError: 

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

629 

630 if prepend is not None: 

631 value = SizedInteger( 

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

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

634 

635 if not internalFormat: 

636 value = cls(value) 

637 

638 return value 

639 

640 @classmethod 

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

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

643 

644 Parameters 

645 ---------- 

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

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

648 """ 

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

650 

651 if prepend is not None: 

652 value = SizedInteger( 

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

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

655 

656 if not internalFormat: 

657 value = cls(value) 

658 

659 return value 

660 

661 def prettyIn(self, value): 

662 if isinstance(value, SizedInteger): 

663 return value 

664 elif octets.isStringType(value): 

665 if not value: 

666 return SizedInteger(0).setBitLength(0) 

667 

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

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

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

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

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

673 else: 

674 raise error.PyAsn1Error( 

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

676 ) 

677 

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

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

680 

681 try: 

682 

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

684 

685 except KeyError: 

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

687 

688 rightmostPosition = max(bitPositions) 

689 

690 number = 0 

691 for bitPosition in bitPositions: 

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

693 

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

695 

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

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

698 

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

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

701 

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

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

704 

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

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

707 

708 elif isinstance(value, BitString): 

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

710 

711 elif isinstance(value, intTypes): 

712 return SizedInteger(value) 

713 

714 else: 

715 raise error.PyAsn1Error( 

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

717 ) 

718 

719 

720class OctetString(base.SimpleAsn1Type): 

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

722 

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

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

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

726 assumes "|encoding|" serialisation. 

727 

728 Keyword Args 

729 ------------ 

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

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

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

733 representing character string to be serialised into octets 

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

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

736 

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

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

739 

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

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

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

743 instantiation. 

744 

745 encoding: :py:class:`str` 

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

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

748 in text string context. 

749 

750 binValue: :py:class:`str` 

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

752 Example: '10110011'. 

753 

754 hexValue: :py:class:`str` 

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

756 Example: 'DEADBEEF'. 

757 

758 Raises 

759 ------ 

760 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

761 On constraint violation or bad initializer. 

762 

763 Examples 

764 -------- 

765 .. code-block:: python 

766 

767 class Icon(OctetString): 

768 ''' 

769 ASN.1 specification: 

770 

771 Icon ::= OCTET STRING 

772 

773 icon1 Icon ::= '001100010011001000110011'B 

774 icon2 Icon ::= '313233'H 

775 ''' 

776 icon1 = Icon.fromBinaryString('001100010011001000110011') 

777 icon2 = Icon.fromHexString('313233') 

778 """ 

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

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

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

782 tagSet = tag.initTagSet( 

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

784 ) 

785 

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

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

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

789 subtypeSpec = constraint.ConstraintsIntersection() 

790 

791 # Optimization for faster codec lookup 

792 typeId = base.SimpleAsn1Type.getTypeId() 

793 

794 defaultBinValue = defaultHexValue = noValue 

795 encoding = 'iso-8859-1' 

796 

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

798 if kwargs: 

799 if value is noValue: 

800 try: 

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

802 

803 except KeyError: 

804 pass 

805 

806 try: 

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

808 

809 except KeyError: 

810 pass 

811 

812 if value is noValue: 

813 if self.defaultBinValue is not noValue: 

814 value = self.fromBinaryString(self.defaultBinValue) 

815 

816 elif self.defaultHexValue is not noValue: 

817 value = self.fromHexString(self.defaultHexValue) 

818 

819 if 'encoding' not in kwargs: 

820 kwargs['encoding'] = self.encoding 

821 

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

823 

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

825 def prettyIn(self, value): 

826 if isinstance(value, str): 

827 return value 

828 

829 elif isinstance(value, unicode): 

830 try: 

831 return value.encode(self.encoding) 

832 

833 except (LookupError, UnicodeEncodeError): 

834 exc = sys.exc_info()[1] 

835 raise error.PyAsn1UnicodeEncodeError( 

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

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

838 ) 

839 

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

841 try: 

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

843 

844 except ValueError: 

845 raise error.PyAsn1Error( 

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

847 ) 

848 

849 else: 

850 return str(value) 

851 

852 def __str__(self): 

853 return str(self._value) 

854 

855 def __unicode__(self): 

856 try: 

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

858 

859 except UnicodeDecodeError: 

860 exc = sys.exc_info()[1] 

861 raise error.PyAsn1UnicodeDecodeError( 

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

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

864 ) 

865 

866 def asOctets(self): 

867 return str(self._value) 

868 

869 def asNumbers(self): 

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

871 

872 else: 

873 def prettyIn(self, value): 

874 if isinstance(value, bytes): 

875 return value 

876 

877 elif isinstance(value, str): 

878 try: 

879 return value.encode(self.encoding) 

880 

881 except UnicodeEncodeError: 

882 exc = sys.exc_info()[1] 

883 raise error.PyAsn1UnicodeEncodeError( 

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

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

886 ) 

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

888 return value.asOctets() 

889 

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

891 return self.prettyIn(str(value)) 

892 

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

894 return self.prettyIn(bytes(value)) 

895 

896 else: 

897 return bytes(value) 

898 

899 def __str__(self): 

900 try: 

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

902 

903 except UnicodeDecodeError: 

904 exc = sys.exc_info()[1] 

905 raise error.PyAsn1UnicodeDecodeError( 

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

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

908 self.__class__.__name__), exc 

909 ) 

910 

911 def __bytes__(self): 

912 return bytes(self._value) 

913 

914 def asOctets(self): 

915 return bytes(self._value) 

916 

917 def asNumbers(self): 

918 return tuple(self._value) 

919 

920 # 

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

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

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

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

925 # text (Py3) representations. 

926 # 

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

928 # reversed to preserve the original behaviour. 

929 # 

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

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

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

933 # the `.asOctets()` method. 

934 # 

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

936 # 

937 

938 def prettyOut(self, value): 

939 return value 

940 

941 def prettyPrint(self, scope=0): 

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

943 value = self.prettyOut(self._value) 

944 

945 if value is not self._value: 

946 return value 

947 

948 numbers = self.asNumbers() 

949 

950 for x in numbers: 

951 # hexify if needed 

952 if x < 32 or x > 126: 

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

954 else: 

955 # this prevents infinite recursion 

956 return OctetString.__str__(self) 

957 

958 @staticmethod 

959 def fromBinaryString(value): 

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

961 

962 Parameters 

963 ---------- 

964 value: :class:`str` 

965 Text string like '1010111' 

966 """ 

967 bitNo = 8 

968 byte = 0 

969 r = [] 

970 for v in value: 

971 if bitNo: 

972 bitNo -= 1 

973 else: 

974 bitNo = 7 

975 r.append(byte) 

976 byte = 0 

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

978 v = int(v) 

979 else: 

980 raise error.PyAsn1Error( 

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

982 ) 

983 byte |= v << bitNo 

984 

985 r.append(byte) 

986 

987 return octets.ints2octs(r) 

988 

989 @staticmethod 

990 def fromHexString(value): 

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

992 

993 Parameters 

994 ---------- 

995 value: :class:`str` 

996 Text string like 'DEADBEEF' 

997 """ 

998 r = [] 

999 p = [] 

1000 for v in value: 

1001 if p: 

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

1003 p = None 

1004 else: 

1005 p = v 

1006 if p: 

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

1008 

1009 return octets.ints2octs(r) 

1010 

1011 # Immutable sequence object protocol 

1012 

1013 def __len__(self): 

1014 return len(self._value) 

1015 

1016 def __getitem__(self, i): 

1017 if i.__class__ is slice: 

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

1019 else: 

1020 return self._value[i] 

1021 

1022 def __iter__(self): 

1023 return iter(self._value) 

1024 

1025 def __contains__(self, value): 

1026 return value in self._value 

1027 

1028 def __add__(self, value): 

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

1030 

1031 def __radd__(self, value): 

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

1033 

1034 def __mul__(self, value): 

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

1036 

1037 def __rmul__(self, value): 

1038 return self * value 

1039 

1040 def __int__(self): 

1041 return int(self._value) 

1042 

1043 def __float__(self): 

1044 return float(self._value) 

1045 

1046 def __reversed__(self): 

1047 return reversed(self._value) 

1048 

1049 

1050class Null(OctetString): 

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

1052 

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

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

1055 (always empty). 

1056 

1057 Keyword Args 

1058 ------------ 

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

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

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

1062 

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

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

1065 

1066 Raises 

1067 ------ 

1068 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1069 On constraint violation or bad initializer. 

1070 

1071 Examples 

1072 -------- 

1073 .. code-block:: python 

1074 

1075 class Ack(Null): 

1076 ''' 

1077 ASN.1 specification: 

1078 

1079 Ack ::= NULL 

1080 ''' 

1081 ack = Ack('') 

1082 """ 

1083 

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

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

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

1087 tagSet = tag.initTagSet( 

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

1089 ) 

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

1091 

1092 # Optimization for faster codec lookup 

1093 typeId = OctetString.getTypeId() 

1094 

1095 def prettyIn(self, value): 

1096 if value: 

1097 return value 

1098 

1099 return octets.str2octs('') 

1100 

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

1102 intTypes = (int, long) 

1103else: 

1104 intTypes = (int,) 

1105 

1106numericTypes = intTypes + (float,) 

1107 

1108 

1109class ObjectIdentifier(base.SimpleAsn1Type): 

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

1111 

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

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

1114 (tuple of non-negative integers). 

1115 

1116 Keyword Args 

1117 ------------ 

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

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

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

1121 

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

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

1124 

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

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

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

1128 instantiation. 

1129 

1130 Raises 

1131 ------ 

1132 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1133 On constraint violation or bad initializer. 

1134 

1135 Examples 

1136 -------- 

1137 .. code-block:: python 

1138 

1139 class ID(ObjectIdentifier): 

1140 ''' 

1141 ASN.1 specification: 

1142 

1143 ID ::= OBJECT IDENTIFIER 

1144 

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

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

1147 ''' 

1148 id_edims = ID('2.6.7') 

1149 id_bp = id_edims + (11,) 

1150 """ 

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

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

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

1154 tagSet = tag.initTagSet( 

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

1156 ) 

1157 

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

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

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

1161 subtypeSpec = constraint.ConstraintsIntersection() 

1162 

1163 # Optimization for faster codec lookup 

1164 typeId = base.SimpleAsn1Type.getTypeId() 

1165 

1166 def __add__(self, other): 

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

1168 

1169 def __radd__(self, other): 

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

1171 

1172 def asTuple(self): 

1173 return self._value 

1174 

1175 # Sequence object protocol 

1176 

1177 def __len__(self): 

1178 return len(self._value) 

1179 

1180 def __getitem__(self, i): 

1181 if i.__class__ is slice: 

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

1183 else: 

1184 return self._value[i] 

1185 

1186 def __iter__(self): 

1187 return iter(self._value) 

1188 

1189 def __contains__(self, value): 

1190 return value in self._value 

1191 

1192 def index(self, suboid): 

1193 return self._value.index(suboid) 

1194 

1195 def isPrefixOf(self, other): 

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

1197 

1198 Parameters 

1199 ---------- 

1200 other: |ASN.1| object 

1201 |ASN.1| object 

1202 

1203 Returns 

1204 ------- 

1205 : :class:`bool` 

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

1207 or :obj:`False` otherwise. 

1208 """ 

1209 l = len(self) 

1210 if l <= len(other): 

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

1212 return True 

1213 return False 

1214 

1215 def prettyIn(self, value): 

1216 if isinstance(value, ObjectIdentifier): 

1217 return tuple(value) 

1218 elif octets.isStringType(value): 

1219 if '-' in value: 

1220 raise error.PyAsn1Error( 

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

1222 ) 

1223 try: 

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

1225 except ValueError: 

1226 raise error.PyAsn1Error( 

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

1228 ) 

1229 

1230 try: 

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

1232 

1233 except (ValueError, TypeError): 

1234 raise error.PyAsn1Error( 

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

1236 ) 

1237 

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

1239 return tupleOfInts 

1240 

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

1242 

1243 def prettyOut(self, value): 

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

1245 

1246 

1247class Real(base.SimpleAsn1Type): 

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

1249 

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

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

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

1253 elements are mantissa, base and exponent. 

1254 

1255 Keyword Args 

1256 ------------ 

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

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

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

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

1261 

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

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

1264 

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

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

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

1268 instantiation. 

1269 

1270 Raises 

1271 ------ 

1272 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1273 On constraint violation or bad initializer. 

1274 

1275 Examples 

1276 -------- 

1277 .. code-block:: python 

1278 

1279 class Pi(Real): 

1280 ''' 

1281 ASN.1 specification: 

1282 

1283 Pi ::= REAL 

1284 

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

1286 

1287 ''' 

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

1289 """ 

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

1291 

1292 try: 

1293 _plusInf = float('inf') 

1294 _minusInf = float('-inf') 

1295 _inf = _plusInf, _minusInf 

1296 

1297 except ValueError: 

1298 # Infinity support is platform and Python dependent 

1299 _plusInf = _minusInf = None 

1300 _inf = () 

1301 

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

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

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

1305 tagSet = tag.initTagSet( 

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

1307 ) 

1308 

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

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

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

1312 subtypeSpec = constraint.ConstraintsIntersection() 

1313 

1314 # Optimization for faster codec lookup 

1315 typeId = base.SimpleAsn1Type.getTypeId() 

1316 

1317 @staticmethod 

1318 def __normalizeBase10(value): 

1319 m, b, e = value 

1320 while m and m % 10 == 0: 

1321 m /= 10 

1322 e += 1 

1323 return m, b, e 

1324 

1325 def prettyIn(self, value): 

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

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

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

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

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

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

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

1333 return value[0] 

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

1335 raise error.PyAsn1Error( 

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

1337 ) 

1338 if value[1] == 10: 

1339 value = self.__normalizeBase10(value) 

1340 return value 

1341 elif isinstance(value, intTypes): 

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

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

1344 if octets.isStringType(value): 

1345 try: 

1346 value = float(value) 

1347 except ValueError: 

1348 raise error.PyAsn1Error( 

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

1350 ) 

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

1352 return value 

1353 else: 

1354 e = 0 

1355 while int(value) != value: 

1356 value *= 10 

1357 e -= 1 

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

1359 elif isinstance(value, Real): 

1360 return tuple(value) 

1361 raise error.PyAsn1Error( 

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

1363 ) 

1364 

1365 def prettyPrint(self, scope=0): 

1366 try: 

1367 return self.prettyOut(float(self)) 

1368 

1369 except OverflowError: 

1370 return '<overflow>' 

1371 

1372 @property 

1373 def isPlusInf(self): 

1374 """Indicate PLUS-INFINITY object value 

1375 

1376 Returns 

1377 ------- 

1378 : :class:`bool` 

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

1380 or :obj:`False` otherwise. 

1381 

1382 """ 

1383 return self._value == self._plusInf 

1384 

1385 @property 

1386 def isMinusInf(self): 

1387 """Indicate MINUS-INFINITY object value 

1388 

1389 Returns 

1390 ------- 

1391 : :class:`bool` 

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

1393 or :obj:`False` otherwise. 

1394 """ 

1395 return self._value == self._minusInf 

1396 

1397 @property 

1398 def isInf(self): 

1399 return self._value in self._inf 

1400 

1401 def __add__(self, value): 

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

1403 

1404 def __radd__(self, value): 

1405 return self + value 

1406 

1407 def __mul__(self, value): 

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

1409 

1410 def __rmul__(self, value): 

1411 return self * value 

1412 

1413 def __sub__(self, value): 

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

1415 

1416 def __rsub__(self, value): 

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

1418 

1419 def __mod__(self, value): 

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

1421 

1422 def __rmod__(self, value): 

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

1424 

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

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

1427 

1428 def __rpow__(self, value): 

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

1430 

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

1432 def __div__(self, value): 

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

1434 

1435 def __rdiv__(self, value): 

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

1437 else: 

1438 def __truediv__(self, value): 

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

1440 

1441 def __rtruediv__(self, value): 

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

1443 

1444 def __divmod__(self, value): 

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

1446 

1447 def __rdivmod__(self, value): 

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

1449 

1450 def __int__(self): 

1451 return int(float(self)) 

1452 

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

1454 def __long__(self): 

1455 return long(float(self)) 

1456 

1457 def __float__(self): 

1458 if self._value in self._inf: 

1459 return self._value 

1460 else: 

1461 return float( 

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

1463 ) 

1464 

1465 def __abs__(self): 

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

1467 

1468 def __pos__(self): 

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

1470 

1471 def __neg__(self): 

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

1473 

1474 def __round__(self, n=0): 

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

1476 if n: 

1477 return self.clone(r) 

1478 else: 

1479 return r 

1480 

1481 def __floor__(self): 

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

1483 

1484 def __ceil__(self): 

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

1486 

1487 def __trunc__(self): 

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

1489 

1490 def __lt__(self, value): 

1491 return float(self) < value 

1492 

1493 def __le__(self, value): 

1494 return float(self) <= value 

1495 

1496 def __eq__(self, value): 

1497 return float(self) == value 

1498 

1499 def __ne__(self, value): 

1500 return float(self) != value 

1501 

1502 def __gt__(self, value): 

1503 return float(self) > value 

1504 

1505 def __ge__(self, value): 

1506 return float(self) >= value 

1507 

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

1509 def __nonzero__(self): 

1510 return bool(float(self)) 

1511 else: 

1512 def __bool__(self): 

1513 return bool(float(self)) 

1514 

1515 __hash__ = base.SimpleAsn1Type.__hash__ 

1516 

1517 def __getitem__(self, idx): 

1518 if self._value in self._inf: 

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

1520 else: 

1521 return self._value[idx] 

1522 

1523 # compatibility stubs 

1524 

1525 def isPlusInfinity(self): 

1526 return self.isPlusInf 

1527 

1528 def isMinusInfinity(self): 

1529 return self.isMinusInf 

1530 

1531 def isInfinity(self): 

1532 return self.isInf 

1533 

1534 

1535class Enumerated(Integer): 

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

1537 

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

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

1540 

1541 Keyword Args 

1542 ------------ 

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

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

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

1546 

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

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

1549 

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

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

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

1553 instantiation. 

1554 

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

1556 Object representing non-default symbolic aliases for numbers 

1557 

1558 Raises 

1559 ------ 

1560 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1561 On constraint violation or bad initializer. 

1562 

1563 Examples 

1564 -------- 

1565 

1566 .. code-block:: python 

1567 

1568 class RadioButton(Enumerated): 

1569 ''' 

1570 ASN.1 specification: 

1571 

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

1573 button3(2) } 

1574 

1575 selected-by-default RadioButton ::= button1 

1576 ''' 

1577 namedValues = NamedValues( 

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

1579 ('button3', 2) 

1580 ) 

1581 

1582 selected_by_default = RadioButton('button1') 

1583 """ 

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

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

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

1587 tagSet = tag.initTagSet( 

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

1589 ) 

1590 

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

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

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

1594 subtypeSpec = constraint.ConstraintsIntersection() 

1595 

1596 # Optimization for faster codec lookup 

1597 typeId = Integer.getTypeId() 

1598 

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

1600 #: representing symbolic aliases for numbers 

1601 namedValues = namedval.NamedValues() 

1602 

1603 

1604# "Structured" ASN.1 types 

1605 

1606class SequenceOfAndSetOfBase(base.ConstructedAsn1Type): 

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

1608 

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

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

1611 

1612 Keyword Args 

1613 ------------ 

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

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

1616 

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

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

1619 

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

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

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

1623 `.isInconsistent` call. 

1624 

1625 Examples 

1626 -------- 

1627 

1628 .. code-block:: python 

1629 

1630 class LotteryDraw(SequenceOf): # SetOf is similar 

1631 ''' 

1632 ASN.1 specification: 

1633 

1634 LotteryDraw ::= SEQUENCE OF INTEGER 

1635 ''' 

1636 componentType = Integer() 

1637 

1638 lotteryDraw = LotteryDraw() 

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

1640 """ 

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

1642 # support positional params for backward compatibility 

1643 if args: 

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

1645 'subtypeSpec'), args): 

1646 if key in kwargs: 

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

1648 kwargs['componentType'] = value 

1649 

1650 self._componentValues = noValue 

1651 

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

1653 

1654 # Python list protocol 

1655 

1656 def __getitem__(self, idx): 

1657 try: 

1658 return self.getComponentByPosition(idx) 

1659 

1660 except error.PyAsn1Error: 

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

1662 

1663 def __setitem__(self, idx, value): 

1664 try: 

1665 self.setComponentByPosition(idx, value) 

1666 

1667 except error.PyAsn1Error: 

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

1669 

1670 def append(self, value): 

1671 if self._componentValues is noValue: 

1672 pos = 0 

1673 

1674 else: 

1675 pos = len(self._componentValues) 

1676 

1677 self[pos] = value 

1678 

1679 def count(self, value): 

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

1681 

1682 def extend(self, values): 

1683 for value in values: 

1684 self.append(value) 

1685 

1686 if self._componentValues is noValue: 

1687 self._componentValues = {} 

1688 

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

1690 if stop is None: 

1691 stop = len(self) 

1692 

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

1694 

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

1696 values = list(values) 

1697 

1698 try: 

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

1700 

1701 except error.PyAsn1Error: 

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

1703 

1704 def reverse(self): 

1705 self._componentValues.reverse() 

1706 

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

1708 self._componentValues = dict( 

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

1710 key=key, reverse=reverse))) 

1711 

1712 def __len__(self): 

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

1714 return 0 

1715 

1716 return max(self._componentValues) + 1 

1717 

1718 def __iter__(self): 

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

1720 yield self.getComponentByPosition(idx) 

1721 

1722 def _cloneComponentValues(self, myClone, cloneValueFlag): 

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

1724 if componentValue is not noValue: 

1725 if isinstance(componentValue, base.ConstructedAsn1Type): 

1726 myClone.setComponentByPosition( 

1727 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

1728 ) 

1729 else: 

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

1731 

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

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

1734 

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

1736 

1737 Parameters 

1738 ---------- 

1739 idx : :class:`int` 

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

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

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

1743 sequence. 

1744 

1745 Keyword Args 

1746 ------------ 

1747 default: :class:`object` 

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

1749 object instead of the requested component. 

1750 

1751 instantiate: :class:`bool` 

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

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

1754 returned. 

1755 

1756 Returns 

1757 ------- 

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

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

1760 

1761 Examples 

1762 -------- 

1763 

1764 .. code-block:: python 

1765 

1766 # can also be SetOf 

1767 class MySequenceOf(SequenceOf): 

1768 componentType = OctetString() 

1769 

1770 s = MySequenceOf() 

1771 

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

1773 s.getComponentByPosition(0) 

1774 

1775 # returns None 

1776 s.getComponentByPosition(0, default=None) 

1777 

1778 s.clear() 

1779 

1780 # returns noValue 

1781 s.getComponentByPosition(0, instantiate=False) 

1782 

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

1784 # object and returns it 

1785 s.getComponentByPosition(0, instantiate=True) 

1786 

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

1788 s.setComponentByPosition(0, 'ABCD') 

1789 

1790 # returns OctetString('ABCD') value object 

1791 s.getComponentByPosition(0, instantiate=False) 

1792 

1793 s.clear() 

1794 

1795 # returns noValue 

1796 s.getComponentByPosition(0, instantiate=False) 

1797 """ 

1798 if isinstance(idx, slice): 

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

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

1801 for subidx in indices[idx]] 

1802 

1803 if idx < 0: 

1804 idx = len(self) + idx 

1805 if idx < 0: 

1806 raise error.PyAsn1Error( 

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

1808 

1809 try: 

1810 componentValue = self._componentValues[idx] 

1811 

1812 except (KeyError, error.PyAsn1Error): 

1813 if not instantiate: 

1814 return default 

1815 

1816 self.setComponentByPosition(idx) 

1817 

1818 componentValue = self._componentValues[idx] 

1819 

1820 if default is noValue or componentValue.isValue: 

1821 return componentValue 

1822 else: 

1823 return default 

1824 

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

1826 verifyConstraints=True, 

1827 matchTags=True, 

1828 matchConstraints=True): 

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

1830 

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

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

1833 

1834 Parameters 

1835 ---------- 

1836 idx: :class:`int` 

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

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

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

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

1841 

1842 Keyword Args 

1843 ------------ 

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

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

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

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

1848 

1849 verifyConstraints: :class:`bool` 

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

1851 

1852 matchTags: :class:`bool` 

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

1854 

1855 matchConstraints: :class:`bool` 

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

1857 

1858 Returns 

1859 ------- 

1860 self 

1861 

1862 Raises 

1863 ------ 

1864 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1865 On constraint violation or bad initializer 

1866 IndexError 

1867 When idx > len(self) 

1868 """ 

1869 if isinstance(idx, slice): 

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

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

1872 for subIdx, subValue in enumerate(value): 

1873 self.setComponentByPosition( 

1874 startIdx + subIdx, subValue, verifyConstraints, 

1875 matchTags, matchConstraints) 

1876 return self 

1877 

1878 if idx < 0: 

1879 idx = len(self) + idx 

1880 if idx < 0: 

1881 raise error.PyAsn1Error( 

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

1883 

1884 componentType = self.componentType 

1885 

1886 if self._componentValues is noValue: 

1887 componentValues = {} 

1888 

1889 else: 

1890 componentValues = self._componentValues 

1891 

1892 currentValue = componentValues.get(idx, noValue) 

1893 

1894 if value is noValue: 

1895 if componentType is not None: 

1896 value = componentType.clone() 

1897 

1898 elif currentValue is noValue: 

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

1900 

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

1902 if (componentType is not None and 

1903 isinstance(componentType, base.SimpleAsn1Type)): 

1904 value = componentType.clone(value=value) 

1905 

1906 elif (currentValue is not noValue and 

1907 isinstance(currentValue, base.SimpleAsn1Type)): 

1908 value = currentValue.clone(value=value) 

1909 

1910 else: 

1911 raise error.PyAsn1Error( 

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

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

1914 

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

1916 subtypeChecker = ( 

1917 self.strictConstraints and 

1918 componentType.isSameTypeWith or 

1919 componentType.isSuperTypeOf) 

1920 

1921 if not subtypeChecker(value, verifyConstraints and matchTags, 

1922 verifyConstraints and matchConstraints): 

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

1924 # additional properties associated with componentType 

1925 if componentType.typeId != Any.typeId: 

1926 raise error.PyAsn1Error( 

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

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

1929 

1930 componentValues[idx] = value 

1931 

1932 self._componentValues = componentValues 

1933 

1934 return self 

1935 

1936 @property 

1937 def componentTagMap(self): 

1938 if self.componentType is not None: 

1939 return self.componentType.tagMap 

1940 

1941 @property 

1942 def components(self): 

1943 return [self._componentValues[idx] 

1944 for idx in sorted(self._componentValues)] 

1945 

1946 def clear(self): 

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

1948 

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

1950 built-in. 

1951 """ 

1952 self._componentValues = {} 

1953 return self 

1954 

1955 def reset(self): 

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

1957 

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

1959 distinction between value and schema objects. 

1960 """ 

1961 self._componentValues = noValue 

1962 return self 

1963 

1964 def prettyPrint(self, scope=0): 

1965 scope += 1 

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

1967 

1968 if not self.isValue: 

1969 return representation 

1970 

1971 for idx, componentValue in enumerate(self): 

1972 representation += ' ' * scope 

1973 if (componentValue is noValue and 

1974 self.componentType is not None): 

1975 representation += '<empty>' 

1976 else: 

1977 representation += componentValue.prettyPrint(scope) 

1978 

1979 return representation 

1980 

1981 def prettyPrintType(self, scope=0): 

1982 scope += 1 

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

1984 if self.componentType is not None: 

1985 representation += ' ' * scope 

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

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

1988 

1989 

1990 @property 

1991 def isValue(self): 

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

1993 

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

1995 

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

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

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

1999 

2000 Returns 

2001 ------- 

2002 : :class:`bool` 

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

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

2005 

2006 Note 

2007 ---- 

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

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

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

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

2012 encoding/decoding serialised ASN.1 contents. 

2013 

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

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

2016 """ 

2017 if self._componentValues is noValue: 

2018 return False 

2019 

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

2021 return False 

2022 

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

2024 if componentValue is noValue or not componentValue.isValue: 

2025 return False 

2026 

2027 return True 

2028 

2029 @property 

2030 def isInconsistent(self): 

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

2032 

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

2034 by `subtypeSpec`. 

2035 

2036 Raises 

2037 ------ 

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

2039 """ 

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

2041 return False 

2042 

2043 if self._componentValues is noValue: 

2044 return True 

2045 

2046 mapping = {} 

2047 

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

2049 # Absent fields are not in the mapping 

2050 if value is noValue: 

2051 continue 

2052 

2053 mapping[idx] = value 

2054 

2055 try: 

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

2057 self.subtypeSpec(mapping) 

2058 

2059 except error.PyAsn1Error: 

2060 exc = sys.exc_info()[1] 

2061 return exc 

2062 

2063 return False 

2064 

2065class SequenceOf(SequenceOfAndSetOfBase): 

2066 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2067 

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

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

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

2071 tagSet = tag.initTagSet( 

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

2073 ) 

2074 

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

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

2077 componentType = None 

2078 

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

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

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

2082 subtypeSpec = constraint.ConstraintsIntersection() 

2083 

2084 # Disambiguation ASN.1 types identification 

2085 typeId = SequenceOfAndSetOfBase.getTypeId() 

2086 

2087 

2088class SetOf(SequenceOfAndSetOfBase): 

2089 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2090 

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

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

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

2094 tagSet = tag.initTagSet( 

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

2096 ) 

2097 

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

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

2100 componentType = None 

2101 

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

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

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

2105 subtypeSpec = constraint.ConstraintsIntersection() 

2106 

2107 # Disambiguation ASN.1 types identification 

2108 typeId = SequenceOfAndSetOfBase.getTypeId() 

2109 

2110 

2111class SequenceAndSetBase(base.ConstructedAsn1Type): 

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

2113 

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

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

2116 

2117 Keyword Args 

2118 ------------ 

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

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

2121 

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

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

2124 

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

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

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

2128 `.isInconsistent` call. 

2129 

2130 Examples 

2131 -------- 

2132 

2133 .. code-block:: python 

2134 

2135 class Description(Sequence): # Set is similar 

2136 ''' 

2137 ASN.1 specification: 

2138 

2139 Description ::= SEQUENCE { 

2140 surname IA5String, 

2141 first-name IA5String OPTIONAL, 

2142 age INTEGER DEFAULT 40 

2143 } 

2144 ''' 

2145 componentType = NamedTypes( 

2146 NamedType('surname', IA5String()), 

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

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

2149 ) 

2150 

2151 descr = Description() 

2152 descr['surname'] = 'Smith' 

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

2154 """ 

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

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

2157 componentType = namedtype.NamedTypes() 

2158 

2159 

2160 class DynamicNames(object): 

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

2162 def __init__(self): 

2163 self._keyToIdxMap = {} 

2164 self._idxToKeyMap = {} 

2165 

2166 def __len__(self): 

2167 return len(self._keyToIdxMap) 

2168 

2169 def __contains__(self, item): 

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

2171 

2172 def __iter__(self): 

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

2174 

2175 def __getitem__(self, item): 

2176 try: 

2177 return self._keyToIdxMap[item] 

2178 

2179 except KeyError: 

2180 return self._idxToKeyMap[item] 

2181 

2182 def getNameByPosition(self, idx): 

2183 try: 

2184 return self._idxToKeyMap[idx] 

2185 

2186 except KeyError: 

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

2188 

2189 def getPositionByName(self, name): 

2190 try: 

2191 return self._keyToIdxMap[name] 

2192 

2193 except KeyError: 

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

2195 

2196 def addField(self, idx): 

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

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

2199 

2200 

2201 def __init__(self, **kwargs): 

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

2203 self._componentTypeLen = len(self.componentType) 

2204 if self._componentTypeLen: 

2205 self._componentValues = [] 

2206 else: 

2207 self._componentValues = noValue 

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

2209 

2210 def __getitem__(self, idx): 

2211 if octets.isStringType(idx): 

2212 try: 

2213 return self.getComponentByName(idx) 

2214 

2215 except error.PyAsn1Error: 

2216 # duck-typing dict 

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

2218 

2219 else: 

2220 try: 

2221 return self.getComponentByPosition(idx) 

2222 

2223 except error.PyAsn1Error: 

2224 # duck-typing list 

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

2226 

2227 def __setitem__(self, idx, value): 

2228 if octets.isStringType(idx): 

2229 try: 

2230 self.setComponentByName(idx, value) 

2231 

2232 except error.PyAsn1Error: 

2233 # duck-typing dict 

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

2235 

2236 else: 

2237 try: 

2238 self.setComponentByPosition(idx, value) 

2239 

2240 except error.PyAsn1Error: 

2241 # duck-typing list 

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

2243 

2244 def __contains__(self, key): 

2245 if self._componentTypeLen: 

2246 return key in self.componentType 

2247 else: 

2248 return key in self._dynamicNames 

2249 

2250 def __len__(self): 

2251 return len(self._componentValues) 

2252 

2253 def __iter__(self): 

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

2255 

2256 # Python dict protocol 

2257 

2258 def values(self): 

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

2260 yield self[idx] 

2261 

2262 def keys(self): 

2263 return iter(self) 

2264 

2265 def items(self): 

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

2267 if self._componentTypeLen: 

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

2269 else: 

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

2271 

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

2273 for k, v in iterValue: 

2274 self[k] = v 

2275 for k in mappingValue: 

2276 self[k] = mappingValue[k] 

2277 

2278 def clear(self): 

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

2280 

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

2282 built-in. 

2283 """ 

2284 self._componentValues = [] 

2285 self._dynamicNames = self.DynamicNames() 

2286 return self 

2287 

2288 def reset(self): 

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

2290 

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

2292 distinction between value and schema objects. 

2293 """ 

2294 self._componentValues = noValue 

2295 self._dynamicNames = self.DynamicNames() 

2296 return self 

2297 

2298 @property 

2299 def components(self): 

2300 return self._componentValues 

2301 

2302 def _cloneComponentValues(self, myClone, cloneValueFlag): 

2303 if self._componentValues is noValue: 

2304 return 

2305 

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

2307 if componentValue is not noValue: 

2308 if isinstance(componentValue, base.ConstructedAsn1Type): 

2309 myClone.setComponentByPosition( 

2310 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

2311 ) 

2312 else: 

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

2314 

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

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

2317 

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

2319 

2320 Parameters 

2321 ---------- 

2322 name: :class:`str` 

2323 |ASN.1| type component name 

2324 

2325 Keyword Args 

2326 ------------ 

2327 default: :class:`object` 

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

2329 object instead of the requested component. 

2330 

2331 instantiate: :class:`bool` 

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

2333 instantiated. 

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

2335 object will be returned. 

2336 

2337 Returns 

2338 ------- 

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

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

2341 component value 

2342 """ 

2343 if self._componentTypeLen: 

2344 idx = self.componentType.getPositionByName(name) 

2345 else: 

2346 try: 

2347 idx = self._dynamicNames.getPositionByName(name) 

2348 

2349 except KeyError: 

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

2351 

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

2353 

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

2355 verifyConstraints=True, 

2356 matchTags=True, 

2357 matchConstraints=True): 

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

2359 

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

2361 

2362 Parameters 

2363 ---------- 

2364 name: :class:`str` 

2365 |ASN.1| type component name 

2366 

2367 Keyword Args 

2368 ------------ 

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

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

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

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

2373 

2374 verifyConstraints: :class:`bool` 

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

2376 

2377 matchTags: :class:`bool` 

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

2379 

2380 matchConstraints: :class:`bool` 

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

2382 

2383 Returns 

2384 ------- 

2385 self 

2386 """ 

2387 if self._componentTypeLen: 

2388 idx = self.componentType.getPositionByName(name) 

2389 else: 

2390 try: 

2391 idx = self._dynamicNames.getPositionByName(name) 

2392 

2393 except KeyError: 

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

2395 

2396 return self.setComponentByPosition( 

2397 idx, value, verifyConstraints, matchTags, matchConstraints 

2398 ) 

2399 

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

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

2402 

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

2404 

2405 Parameters 

2406 ---------- 

2407 idx: :class:`int` 

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

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

2410 instantiated. 

2411 

2412 Keyword Args 

2413 ------------ 

2414 default: :class:`object` 

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

2416 object instead of the requested component. 

2417 

2418 instantiate: :class:`bool` 

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

2420 instantiated. 

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

2422 object will be returned. 

2423 

2424 Returns 

2425 ------- 

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

2427 a PyASN1 object 

2428 

2429 Examples 

2430 -------- 

2431 

2432 .. code-block:: python 

2433 

2434 # can also be Set 

2435 class MySequence(Sequence): 

2436 componentType = NamedTypes( 

2437 NamedType('id', OctetString()) 

2438 ) 

2439 

2440 s = MySequence() 

2441 

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

2443 s.getComponentByPosition(0) 

2444 

2445 # returns None 

2446 s.getComponentByPosition(0, default=None) 

2447 

2448 s.clear() 

2449 

2450 # returns noValue 

2451 s.getComponentByPosition(0, instantiate=False) 

2452 

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

2454 # object and returns it 

2455 s.getComponentByPosition(0, instantiate=True) 

2456 

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

2458 s.setComponentByPosition(0, 'ABCD') 

2459 

2460 # returns OctetString('ABCD') value object 

2461 s.getComponentByPosition(0, instantiate=False) 

2462 

2463 s.clear() 

2464 

2465 # returns noValue 

2466 s.getComponentByPosition(0, instantiate=False) 

2467 """ 

2468 try: 

2469 if self._componentValues is noValue: 

2470 componentValue = noValue 

2471 

2472 else: 

2473 componentValue = self._componentValues[idx] 

2474 

2475 except IndexError: 

2476 componentValue = noValue 

2477 

2478 if not instantiate: 

2479 if componentValue is noValue or not componentValue.isValue: 

2480 return default 

2481 else: 

2482 return componentValue 

2483 

2484 if componentValue is noValue: 

2485 self.setComponentByPosition(idx) 

2486 

2487 componentValue = self._componentValues[idx] 

2488 

2489 if default is noValue or componentValue.isValue: 

2490 return componentValue 

2491 else: 

2492 return default 

2493 

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

2495 verifyConstraints=True, 

2496 matchTags=True, 

2497 matchConstraints=True): 

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

2499 

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

2501 

2502 Parameters 

2503 ---------- 

2504 idx : :class:`int` 

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

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

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

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

2509 

2510 Keyword Args 

2511 ------------ 

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

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

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

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

2516 

2517 verifyConstraints : :class:`bool` 

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

2519 

2520 matchTags: :class:`bool` 

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

2522 

2523 matchConstraints: :class:`bool` 

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

2525 

2526 Returns 

2527 ------- 

2528 self 

2529 """ 

2530 componentType = self.componentType 

2531 componentTypeLen = self._componentTypeLen 

2532 

2533 if self._componentValues is noValue: 

2534 componentValues = [] 

2535 

2536 else: 

2537 componentValues = self._componentValues 

2538 

2539 try: 

2540 currentValue = componentValues[idx] 

2541 

2542 except IndexError: 

2543 currentValue = noValue 

2544 if componentTypeLen: 

2545 if componentTypeLen < idx: 

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

2547 

2548 componentValues = [noValue] * componentTypeLen 

2549 

2550 if value is noValue: 

2551 if componentTypeLen: 

2552 value = componentType.getTypeByPosition(idx) 

2553 if isinstance(value, base.ConstructedAsn1Type): 

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

2555 

2556 elif currentValue is noValue: 

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

2558 

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

2560 if componentTypeLen: 

2561 subComponentType = componentType.getTypeByPosition(idx) 

2562 if isinstance(subComponentType, base.SimpleAsn1Type): 

2563 value = subComponentType.clone(value=value) 

2564 

2565 else: 

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

2567 

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

2569 value = currentValue.clone(value=value) 

2570 

2571 else: 

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

2573 

2574 elif ((verifyConstraints or matchTags or matchConstraints) and 

2575 componentTypeLen): 

2576 subComponentType = componentType.getTypeByPosition(idx) 

2577 if subComponentType is not noValue: 

2578 subtypeChecker = (self.strictConstraints and 

2579 subComponentType.isSameTypeWith or 

2580 subComponentType.isSuperTypeOf) 

2581 

2582 if not subtypeChecker(value, verifyConstraints and matchTags, 

2583 verifyConstraints and matchConstraints): 

2584 if not componentType[idx].openType: 

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

2586 

2587 if componentTypeLen or idx in self._dynamicNames: 

2588 componentValues[idx] = value 

2589 

2590 elif len(componentValues) == idx: 

2591 componentValues.append(value) 

2592 self._dynamicNames.addField(idx) 

2593 

2594 else: 

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

2596 

2597 self._componentValues = componentValues 

2598 

2599 return self 

2600 

2601 @property 

2602 def isValue(self): 

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

2604 

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

2606 

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

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

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

2610 

2611 Returns 

2612 ------- 

2613 : :class:`bool` 

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

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

2616 normal value. 

2617 

2618 Note 

2619 ---- 

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

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

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

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

2624 encoding/decoding serialised ASN.1 contents. 

2625 

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

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

2628 

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

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

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

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

2633 components are normally value objects by default. 

2634 """ 

2635 if self._componentValues is noValue: 

2636 return False 

2637 

2638 componentType = self.componentType 

2639 

2640 if componentType: 

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

2642 if subComponentType.isDefaulted or subComponentType.isOptional: 

2643 continue 

2644 

2645 if not self._componentValues: 

2646 return False 

2647 

2648 componentValue = self._componentValues[idx] 

2649 if componentValue is noValue or not componentValue.isValue: 

2650 return False 

2651 

2652 else: 

2653 for componentValue in self._componentValues: 

2654 if componentValue is noValue or not componentValue.isValue: 

2655 return False 

2656 

2657 return True 

2658 

2659 @property 

2660 def isInconsistent(self): 

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

2662 

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

2664 by `subtypeSpec`. 

2665 

2666 Raises 

2667 ------ 

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

2669 """ 

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

2671 return False 

2672 

2673 if self._componentValues is noValue: 

2674 return True 

2675 

2676 mapping = {} 

2677 

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

2679 # Absent fields are not in the mapping 

2680 if value is noValue: 

2681 continue 

2682 

2683 name = self.componentType.getNameByPosition(idx) 

2684 

2685 mapping[name] = value 

2686 

2687 try: 

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

2689 self.subtypeSpec(mapping) 

2690 

2691 except error.PyAsn1Error: 

2692 exc = sys.exc_info()[1] 

2693 return exc 

2694 

2695 return False 

2696 

2697 def prettyPrint(self, scope=0): 

2698 """Return an object representation string. 

2699 

2700 Returns 

2701 ------- 

2702 : :class:`str` 

2703 Human-friendly object representation. 

2704 """ 

2705 scope += 1 

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

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

2708 if componentValue is not noValue and componentValue.isValue: 

2709 representation += ' ' * scope 

2710 if self.componentType: 

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

2712 else: 

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

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

2715 representation, componentValue.prettyPrint(scope) 

2716 ) 

2717 return representation 

2718 

2719 def prettyPrintType(self, scope=0): 

2720 scope += 1 

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

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

2723 representation += ' ' * scope 

2724 if self.componentType: 

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

2726 else: 

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

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

2729 representation, componentType.prettyPrintType(scope) 

2730 ) 

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

2732 

2733 # backward compatibility 

2734 

2735 def setDefaultComponents(self): 

2736 return self 

2737 

2738 def getComponentType(self): 

2739 if self._componentTypeLen: 

2740 return self.componentType 

2741 

2742 def getNameByPosition(self, idx): 

2743 if self._componentTypeLen: 

2744 return self.componentType[idx].name 

2745 

2746class Sequence(SequenceAndSetBase): 

2747 __doc__ = SequenceAndSetBase.__doc__ 

2748 

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

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

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

2752 tagSet = tag.initTagSet( 

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

2754 ) 

2755 

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

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

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

2759 subtypeSpec = constraint.ConstraintsIntersection() 

2760 

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

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

2763 componentType = namedtype.NamedTypes() 

2764 

2765 # Disambiguation ASN.1 types identification 

2766 typeId = SequenceAndSetBase.getTypeId() 

2767 

2768 # backward compatibility 

2769 

2770 def getComponentTagMapNearPosition(self, idx): 

2771 if self.componentType: 

2772 return self.componentType.getTagMapNearPosition(idx) 

2773 

2774 def getComponentPositionNearType(self, tagSet, idx): 

2775 if self.componentType: 

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

2777 else: 

2778 return idx 

2779 

2780 

2781class Set(SequenceAndSetBase): 

2782 __doc__ = SequenceAndSetBase.__doc__ 

2783 

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

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

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

2787 tagSet = tag.initTagSet( 

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

2789 ) 

2790 

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

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

2793 componentType = namedtype.NamedTypes() 

2794 

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

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

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

2798 subtypeSpec = constraint.ConstraintsIntersection() 

2799 

2800 # Disambiguation ASN.1 types identification 

2801 typeId = SequenceAndSetBase.getTypeId() 

2802 

2803 def getComponent(self, innerFlag=False): 

2804 return self 

2805 

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

2807 instantiate=True, innerFlag=False): 

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

2809 

2810 Parameters 

2811 ---------- 

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

2813 Object representing ASN.1 tags to identify one of 

2814 |ASN.1| object component 

2815 

2816 Keyword Args 

2817 ------------ 

2818 default: :class:`object` 

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

2820 object instead of the requested component. 

2821 

2822 instantiate: :class:`bool` 

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

2824 instantiated. 

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

2826 object will be returned. 

2827 

2828 Returns 

2829 ------- 

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

2831 a pyasn1 object 

2832 """ 

2833 componentValue = self.getComponentByPosition( 

2834 self.componentType.getPositionByType(tagSet), 

2835 default=default, instantiate=instantiate 

2836 ) 

2837 if innerFlag and isinstance(componentValue, Set): 

2838 # get inner component by inner tagSet 

2839 return componentValue.getComponent(innerFlag=True) 

2840 else: 

2841 # get outer component by inner tagSet 

2842 return componentValue 

2843 

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

2845 verifyConstraints=True, 

2846 matchTags=True, 

2847 matchConstraints=True, 

2848 innerFlag=False): 

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

2850 

2851 Parameters 

2852 ---------- 

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

2854 Object representing ASN.1 tags to identify one of 

2855 |ASN.1| object component 

2856 

2857 Keyword Args 

2858 ------------ 

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

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

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

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

2863 

2864 verifyConstraints : :class:`bool` 

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

2866 

2867 matchTags: :class:`bool` 

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

2869 

2870 matchConstraints: :class:`bool` 

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

2872 

2873 innerFlag: :class:`bool` 

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

2875 

2876 Returns 

2877 ------- 

2878 self 

2879 """ 

2880 idx = self.componentType.getPositionByType(tagSet) 

2881 

2882 if innerFlag: # set inner component by inner tagSet 

2883 componentType = self.componentType.getTypeByPosition(idx) 

2884 

2885 if componentType.tagSet: 

2886 return self.setComponentByPosition( 

2887 idx, value, verifyConstraints, matchTags, matchConstraints 

2888 ) 

2889 else: 

2890 componentType = self.getComponentByPosition(idx) 

2891 return componentType.setComponentByType( 

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

2893 ) 

2894 else: # set outer component by inner tagSet 

2895 return self.setComponentByPosition( 

2896 idx, value, verifyConstraints, matchTags, matchConstraints 

2897 ) 

2898 

2899 @property 

2900 def componentTagMap(self): 

2901 if self.componentType: 

2902 return self.componentType.tagMapUnique 

2903 

2904 

2905class Choice(Set): 

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

2907 

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

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

2910 

2911 Keyword Args 

2912 ------------ 

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

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

2915 

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

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

2918 

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

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

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

2922 `.isInconsistent` call. 

2923 

2924 Examples 

2925 -------- 

2926 

2927 .. code-block:: python 

2928 

2929 class Afters(Choice): 

2930 ''' 

2931 ASN.1 specification: 

2932 

2933 Afters ::= CHOICE { 

2934 cheese [0] IA5String, 

2935 dessert [1] IA5String 

2936 } 

2937 ''' 

2938 componentType = NamedTypes( 

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

2940 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 

2941 ), 

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

2943 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 

2944 ) 

2945 ) 

2946 

2947 afters = Afters() 

2948 afters['cheese'] = 'Mascarpone' 

2949 """ 

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

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

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

2953 tagSet = tag.TagSet() # untagged 

2954 

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

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

2957 componentType = namedtype.NamedTypes() 

2958 

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

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

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

2962 subtypeSpec = constraint.ConstraintsIntersection( 

2963 constraint.ValueSizeConstraint(1, 1) 

2964 ) 

2965 

2966 # Disambiguation ASN.1 types identification 

2967 typeId = Set.getTypeId() 

2968 

2969 _currentIdx = None 

2970 

2971 def __eq__(self, other): 

2972 if self._componentValues: 

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

2974 return NotImplemented 

2975 

2976 def __ne__(self, other): 

2977 if self._componentValues: 

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

2979 return NotImplemented 

2980 

2981 def __lt__(self, other): 

2982 if self._componentValues: 

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

2984 return NotImplemented 

2985 

2986 def __le__(self, other): 

2987 if self._componentValues: 

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

2989 return NotImplemented 

2990 

2991 def __gt__(self, other): 

2992 if self._componentValues: 

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

2994 return NotImplemented 

2995 

2996 def __ge__(self, other): 

2997 if self._componentValues: 

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

2999 return NotImplemented 

3000 

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

3002 def __nonzero__(self): 

3003 return self._componentValues and True or False 

3004 else: 

3005 def __bool__(self): 

3006 return self._componentValues and True or False 

3007 

3008 def __len__(self): 

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

3010 

3011 def __contains__(self, key): 

3012 if self._currentIdx is None: 

3013 return False 

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

3015 

3016 def __iter__(self): 

3017 if self._currentIdx is None: 

3018 raise StopIteration 

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

3020 

3021 # Python dict protocol 

3022 

3023 def values(self): 

3024 if self._currentIdx is not None: 

3025 yield self._componentValues[self._currentIdx] 

3026 

3027 def keys(self): 

3028 if self._currentIdx is not None: 

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

3030 

3031 def items(self): 

3032 if self._currentIdx is not None: 

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

3034 

3035 def checkConsistency(self): 

3036 if self._currentIdx is None: 

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

3038 

3039 def _cloneComponentValues(self, myClone, cloneValueFlag): 

3040 try: 

3041 component = self.getComponent() 

3042 except error.PyAsn1Error: 

3043 pass 

3044 else: 

3045 if isinstance(component, Choice): 

3046 tagSet = component.effectiveTagSet 

3047 else: 

3048 tagSet = component.tagSet 

3049 if isinstance(component, base.ConstructedAsn1Type): 

3050 myClone.setComponentByType( 

3051 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 

3052 ) 

3053 else: 

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

3055 

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

3057 __doc__ = Set.__doc__ 

3058 

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

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

3061 instantiate=instantiate) 

3062 

3063 return self._componentValues[idx] 

3064 

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

3066 verifyConstraints=True, 

3067 matchTags=True, 

3068 matchConstraints=True): 

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

3070 

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

3072 

3073 Parameters 

3074 ---------- 

3075 idx: :class:`int` 

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

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

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

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

3080 

3081 Keyword Args 

3082 ------------ 

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

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

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

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

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

3088 

3089 verifyConstraints : :class:`bool` 

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

3091 

3092 matchTags: :class:`bool` 

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

3094 

3095 matchConstraints: :class:`bool` 

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

3097 

3098 Returns 

3099 ------- 

3100 self 

3101 """ 

3102 oldIdx = self._currentIdx 

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

3104 self._currentIdx = idx 

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

3106 self._componentValues[oldIdx] = noValue 

3107 return self 

3108 

3109 @property 

3110 def effectiveTagSet(self): 

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

3112 if self.tagSet: 

3113 return self.tagSet 

3114 else: 

3115 component = self.getComponent() 

3116 return component.effectiveTagSet 

3117 

3118 @property 

3119 def tagMap(self): 

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

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

3122 """ 

3123 if self.tagSet: 

3124 return Set.tagMap.fget(self) 

3125 else: 

3126 return self.componentType.tagMapUnique 

3127 

3128 def getComponent(self, innerFlag=False): 

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

3130 

3131 Returns 

3132 ------- 

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

3134 a PyASN1 object 

3135 """ 

3136 if self._currentIdx is None: 

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

3138 else: 

3139 c = self._componentValues[self._currentIdx] 

3140 if innerFlag and isinstance(c, Choice): 

3141 return c.getComponent(innerFlag) 

3142 else: 

3143 return c 

3144 

3145 def getName(self, innerFlag=False): 

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

3147 

3148 Returns 

3149 ------- 

3150 : :py:class:`str` 

3151 |ASN.1| component name 

3152 """ 

3153 if self._currentIdx is None: 

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

3155 else: 

3156 if innerFlag: 

3157 c = self._componentValues[self._currentIdx] 

3158 if isinstance(c, Choice): 

3159 return c.getName(innerFlag) 

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

3161 

3162 @property 

3163 def isValue(self): 

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

3165 

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

3167 

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

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

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

3171 

3172 Returns 

3173 ------- 

3174 : :class:`bool` 

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

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

3177 value. 

3178 

3179 Note 

3180 ---- 

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

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

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

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

3185 encoding/decoding serialised ASN.1 contents. 

3186 

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

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

3189 """ 

3190 if self._currentIdx is None: 

3191 return False 

3192 

3193 componentValue = self._componentValues[self._currentIdx] 

3194 

3195 return componentValue is not noValue and componentValue.isValue 

3196 

3197 def clear(self): 

3198 self._currentIdx = None 

3199 return Set.clear(self) 

3200 

3201 # compatibility stubs 

3202 

3203 def getMinTagSet(self): 

3204 return self.minTagSet 

3205 

3206 

3207class Any(OctetString): 

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

3209 

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

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

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

3213 "|encoding|" serialisation. 

3214 

3215 Keyword Args 

3216 ------------ 

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

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

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

3220 representing character string to be serialised into octets (note 

3221 `encoding` parameter) or |ASN.1| object. 

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

3223 

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

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

3226 

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

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

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

3230 instantiation. 

3231 

3232 encoding: :py:class:`str` 

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

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

3235 in text string context. 

3236 

3237 binValue: :py:class:`str` 

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

3239 Example: '10110011'. 

3240 

3241 hexValue: :py:class:`str` 

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

3243 Example: 'DEADBEEF'. 

3244 

3245 Raises 

3246 ------ 

3247 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

3248 On constraint violation or bad initializer. 

3249 

3250 Examples 

3251 -------- 

3252 .. code-block:: python 

3253 

3254 class Error(Sequence): 

3255 ''' 

3256 ASN.1 specification: 

3257 

3258 Error ::= SEQUENCE { 

3259 code INTEGER, 

3260 parameter ANY DEFINED BY code -- Either INTEGER or REAL 

3261 } 

3262 ''' 

3263 componentType=NamedTypes( 

3264 NamedType('code', Integer()), 

3265 NamedType('parameter', Any(), 

3266 openType=OpenType('code', {1: Integer(), 

3267 2: Real()})) 

3268 ) 

3269 

3270 error = Error() 

3271 error['code'] = 1 

3272 error['parameter'] = Integer(1234) 

3273 """ 

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

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

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

3277 tagSet = tag.TagSet() # untagged 

3278 

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

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

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

3282 subtypeSpec = constraint.ConstraintsIntersection() 

3283 

3284 # Disambiguation ASN.1 types identification 

3285 typeId = OctetString.getTypeId() 

3286 

3287 @property 

3288 def tagMap(self): 

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

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

3291 """ 

3292 try: 

3293 return self._tagMap 

3294 

3295 except AttributeError: 

3296 self._tagMap = tagmap.TagMap( 

3297 {self.tagSet: self}, 

3298 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 

3299 self 

3300 ) 

3301 

3302 return self._tagMap 

3303 

3304# XXX 

3305# coercion rules?