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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1310 statements  

1# 

2# This file is part of pyasn1 software. 

3# 

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

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

6# 

7import math 

8import sys 

9 

10from pyasn1 import error 

11from pyasn1.codec.ber import eoo 

12from pyasn1.compat import integer 

13from pyasn1.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 RelativeOID(base.SimpleAsn1Type): 

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

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

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

1251 (tuple of non-negative integers). 

1252 Keyword Args 

1253 ------------ 

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

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

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

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

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

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

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

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

1262 instantiation. 

1263 Raises 

1264 ------ 

1265 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1266 On constraint violation or bad initializer. 

1267 Examples 

1268 -------- 

1269 .. code-block:: python 

1270 class RelOID(RelativeOID): 

1271 ''' 

1272 ASN.1 specification: 

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

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

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

1276 ''' 

1277 id_pad_null = RelOID('0') 

1278 id_pad_once = RelOID('5.6') 

1279 id_pad_twice = id_pad_once + (7,) 

1280 """ 

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

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

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

1284 tagSet = tag.initTagSet( 

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

1286 ) 

1287 

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

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

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

1291 subtypeSpec = constraint.ConstraintsIntersection() 

1292 

1293 # Optimization for faster codec lookup 

1294 typeId = base.SimpleAsn1Type.getTypeId() 

1295 

1296 def __add__(self, other): 

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

1298 

1299 def __radd__(self, other): 

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

1301 

1302 def asTuple(self): 

1303 return self._value 

1304 

1305 # Sequence object protocol 

1306 

1307 def __len__(self): 

1308 return len(self._value) 

1309 

1310 def __getitem__(self, i): 

1311 if i.__class__ is slice: 

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

1313 else: 

1314 return self._value[i] 

1315 

1316 def __iter__(self): 

1317 return iter(self._value) 

1318 

1319 def __contains__(self, value): 

1320 return value in self._value 

1321 

1322 def index(self, suboid): 

1323 return self._value.index(suboid) 

1324 

1325 def isPrefixOf(self, other): 

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

1327 Parameters 

1328 ---------- 

1329 other: |ASN.1| object 

1330 |ASN.1| object 

1331 Returns 

1332 ------- 

1333 : :class:`bool` 

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

1335 or :obj:`False` otherwise. 

1336 """ 

1337 l = len(self) 

1338 if l <= len(other): 

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

1340 return True 

1341 return False 

1342 

1343 def prettyIn(self, value): 

1344 if isinstance(value, RelativeOID): 

1345 return tuple(value) 

1346 elif octets.isStringType(value): 

1347 if '-' in value: 

1348 raise error.PyAsn1Error( 

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

1350 ) 

1351 try: 

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

1353 except ValueError: 

1354 raise error.PyAsn1Error( 

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

1356 ) 

1357 

1358 try: 

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

1360 

1361 except (ValueError, TypeError): 

1362 raise error.PyAsn1Error( 

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

1364 ) 

1365 

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

1367 return tupleOfInts 

1368 

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

1370 

1371 def prettyOut(self, value): 

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

1373 

1374 

1375class Real(base.SimpleAsn1Type): 

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

1377 

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

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

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

1381 elements are mantissa, base and exponent. 

1382 

1383 Keyword Args 

1384 ------------ 

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

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

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

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

1389 

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

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

1392 

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

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

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

1396 instantiation. 

1397 

1398 Raises 

1399 ------ 

1400 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1401 On constraint violation or bad initializer. 

1402 

1403 Examples 

1404 -------- 

1405 .. code-block:: python 

1406 

1407 class Pi(Real): 

1408 ''' 

1409 ASN.1 specification: 

1410 

1411 Pi ::= REAL 

1412 

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

1414 

1415 ''' 

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

1417 """ 

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

1419 

1420 try: 

1421 _plusInf = float('inf') 

1422 _minusInf = float('-inf') 

1423 _inf = _plusInf, _minusInf 

1424 

1425 except ValueError: 

1426 # Infinity support is platform and Python dependent 

1427 _plusInf = _minusInf = None 

1428 _inf = () 

1429 

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

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

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

1433 tagSet = tag.initTagSet( 

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

1435 ) 

1436 

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

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

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

1440 subtypeSpec = constraint.ConstraintsIntersection() 

1441 

1442 # Optimization for faster codec lookup 

1443 typeId = base.SimpleAsn1Type.getTypeId() 

1444 

1445 @staticmethod 

1446 def __normalizeBase10(value): 

1447 m, b, e = value 

1448 while m and m % 10 == 0: 

1449 m /= 10 

1450 e += 1 

1451 return m, b, e 

1452 

1453 def prettyIn(self, value): 

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

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

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

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

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

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

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

1461 return value[0] 

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

1463 raise error.PyAsn1Error( 

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

1465 ) 

1466 if value[1] == 10: 

1467 value = self.__normalizeBase10(value) 

1468 return value 

1469 elif isinstance(value, intTypes): 

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

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

1472 if octets.isStringType(value): 

1473 try: 

1474 value = float(value) 

1475 except ValueError: 

1476 raise error.PyAsn1Error( 

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

1478 ) 

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

1480 return value 

1481 else: 

1482 e = 0 

1483 while int(value) != value: 

1484 value *= 10 

1485 e -= 1 

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

1487 elif isinstance(value, Real): 

1488 return tuple(value) 

1489 raise error.PyAsn1Error( 

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

1491 ) 

1492 

1493 def prettyPrint(self, scope=0): 

1494 try: 

1495 return self.prettyOut(float(self)) 

1496 

1497 except OverflowError: 

1498 return '<overflow>' 

1499 

1500 @property 

1501 def isPlusInf(self): 

1502 """Indicate PLUS-INFINITY object value 

1503 

1504 Returns 

1505 ------- 

1506 : :class:`bool` 

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

1508 or :obj:`False` otherwise. 

1509 

1510 """ 

1511 return self._value == self._plusInf 

1512 

1513 @property 

1514 def isMinusInf(self): 

1515 """Indicate MINUS-INFINITY object value 

1516 

1517 Returns 

1518 ------- 

1519 : :class:`bool` 

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

1521 or :obj:`False` otherwise. 

1522 """ 

1523 return self._value == self._minusInf 

1524 

1525 @property 

1526 def isInf(self): 

1527 return self._value in self._inf 

1528 

1529 def __add__(self, value): 

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

1531 

1532 def __radd__(self, value): 

1533 return self + value 

1534 

1535 def __mul__(self, value): 

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

1537 

1538 def __rmul__(self, value): 

1539 return self * value 

1540 

1541 def __sub__(self, value): 

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

1543 

1544 def __rsub__(self, value): 

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

1546 

1547 def __mod__(self, value): 

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

1549 

1550 def __rmod__(self, value): 

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

1552 

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

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

1555 

1556 def __rpow__(self, value): 

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

1558 

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

1560 def __div__(self, value): 

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

1562 

1563 def __rdiv__(self, value): 

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

1565 else: 

1566 def __truediv__(self, value): 

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

1568 

1569 def __rtruediv__(self, value): 

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

1571 

1572 def __divmod__(self, value): 

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

1574 

1575 def __rdivmod__(self, value): 

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

1577 

1578 def __int__(self): 

1579 return int(float(self)) 

1580 

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

1582 def __long__(self): 

1583 return long(float(self)) 

1584 

1585 def __float__(self): 

1586 if self._value in self._inf: 

1587 return self._value 

1588 else: 

1589 return float( 

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

1591 ) 

1592 

1593 def __abs__(self): 

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

1595 

1596 def __pos__(self): 

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

1598 

1599 def __neg__(self): 

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

1601 

1602 def __round__(self, n=0): 

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

1604 if n: 

1605 return self.clone(r) 

1606 else: 

1607 return r 

1608 

1609 def __floor__(self): 

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

1611 

1612 def __ceil__(self): 

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

1614 

1615 def __trunc__(self): 

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

1617 

1618 def __lt__(self, value): 

1619 return float(self) < value 

1620 

1621 def __le__(self, value): 

1622 return float(self) <= value 

1623 

1624 def __eq__(self, value): 

1625 return float(self) == value 

1626 

1627 def __ne__(self, value): 

1628 return float(self) != value 

1629 

1630 def __gt__(self, value): 

1631 return float(self) > value 

1632 

1633 def __ge__(self, value): 

1634 return float(self) >= value 

1635 

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

1637 def __nonzero__(self): 

1638 return bool(float(self)) 

1639 else: 

1640 def __bool__(self): 

1641 return bool(float(self)) 

1642 

1643 __hash__ = base.SimpleAsn1Type.__hash__ 

1644 

1645 def __getitem__(self, idx): 

1646 if self._value in self._inf: 

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

1648 else: 

1649 return self._value[idx] 

1650 

1651 # compatibility stubs 

1652 

1653 def isPlusInfinity(self): 

1654 return self.isPlusInf 

1655 

1656 def isMinusInfinity(self): 

1657 return self.isMinusInf 

1658 

1659 def isInfinity(self): 

1660 return self.isInf 

1661 

1662 

1663class Enumerated(Integer): 

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

1665 

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

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

1668 

1669 Keyword Args 

1670 ------------ 

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

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

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

1674 

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

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

1677 

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

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

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

1681 instantiation. 

1682 

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

1684 Object representing non-default symbolic aliases for numbers 

1685 

1686 Raises 

1687 ------ 

1688 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1689 On constraint violation or bad initializer. 

1690 

1691 Examples 

1692 -------- 

1693 

1694 .. code-block:: python 

1695 

1696 class RadioButton(Enumerated): 

1697 ''' 

1698 ASN.1 specification: 

1699 

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

1701 button3(2) } 

1702 

1703 selected-by-default RadioButton ::= button1 

1704 ''' 

1705 namedValues = NamedValues( 

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

1707 ('button3', 2) 

1708 ) 

1709 

1710 selected_by_default = RadioButton('button1') 

1711 """ 

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

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

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

1715 tagSet = tag.initTagSet( 

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

1717 ) 

1718 

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

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

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

1722 subtypeSpec = constraint.ConstraintsIntersection() 

1723 

1724 # Optimization for faster codec lookup 

1725 typeId = Integer.getTypeId() 

1726 

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

1728 #: representing symbolic aliases for numbers 

1729 namedValues = namedval.NamedValues() 

1730 

1731 

1732# "Structured" ASN.1 types 

1733 

1734class SequenceOfAndSetOfBase(base.ConstructedAsn1Type): 

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

1736 

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

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

1739 

1740 Keyword Args 

1741 ------------ 

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

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

1744 

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

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

1747 

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

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

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

1751 `.isInconsistent` call. 

1752 

1753 Examples 

1754 -------- 

1755 

1756 .. code-block:: python 

1757 

1758 class LotteryDraw(SequenceOf): # SetOf is similar 

1759 ''' 

1760 ASN.1 specification: 

1761 

1762 LotteryDraw ::= SEQUENCE OF INTEGER 

1763 ''' 

1764 componentType = Integer() 

1765 

1766 lotteryDraw = LotteryDraw() 

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

1768 """ 

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

1770 # support positional params for backward compatibility 

1771 if args: 

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

1773 'subtypeSpec'), args): 

1774 if key in kwargs: 

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

1776 kwargs['componentType'] = value 

1777 

1778 self._componentValues = noValue 

1779 

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

1781 

1782 # Python list protocol 

1783 

1784 def __getitem__(self, idx): 

1785 try: 

1786 return self.getComponentByPosition(idx) 

1787 

1788 except error.PyAsn1Error: 

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

1790 

1791 def __setitem__(self, idx, value): 

1792 try: 

1793 self.setComponentByPosition(idx, value) 

1794 

1795 except error.PyAsn1Error: 

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

1797 

1798 def append(self, value): 

1799 if self._componentValues is noValue: 

1800 pos = 0 

1801 

1802 else: 

1803 pos = len(self._componentValues) 

1804 

1805 self[pos] = value 

1806 

1807 def count(self, value): 

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

1809 

1810 def extend(self, values): 

1811 for value in values: 

1812 self.append(value) 

1813 

1814 if self._componentValues is noValue: 

1815 self._componentValues = {} 

1816 

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

1818 if stop is None: 

1819 stop = len(self) 

1820 

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

1822 

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

1824 values = list(values) 

1825 

1826 try: 

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

1828 

1829 except error.PyAsn1Error: 

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

1831 

1832 def reverse(self): 

1833 self._componentValues.reverse() 

1834 

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

1836 self._componentValues = dict( 

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

1838 key=key, reverse=reverse))) 

1839 

1840 def __len__(self): 

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

1842 return 0 

1843 

1844 return max(self._componentValues) + 1 

1845 

1846 def __iter__(self): 

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

1848 yield self.getComponentByPosition(idx) 

1849 

1850 def _cloneComponentValues(self, myClone, cloneValueFlag): 

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

1852 if componentValue is not noValue: 

1853 if isinstance(componentValue, base.ConstructedAsn1Type): 

1854 myClone.setComponentByPosition( 

1855 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

1856 ) 

1857 else: 

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

1859 

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

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

1862 

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

1864 

1865 Parameters 

1866 ---------- 

1867 idx : :class:`int` 

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

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

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

1871 sequence. 

1872 

1873 Keyword Args 

1874 ------------ 

1875 default: :class:`object` 

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

1877 object instead of the requested component. 

1878 

1879 instantiate: :class:`bool` 

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

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

1882 returned. 

1883 

1884 Returns 

1885 ------- 

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

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

1888 

1889 Examples 

1890 -------- 

1891 

1892 .. code-block:: python 

1893 

1894 # can also be SetOf 

1895 class MySequenceOf(SequenceOf): 

1896 componentType = OctetString() 

1897 

1898 s = MySequenceOf() 

1899 

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

1901 s.getComponentByPosition(0) 

1902 

1903 # returns None 

1904 s.getComponentByPosition(0, default=None) 

1905 

1906 s.clear() 

1907 

1908 # returns noValue 

1909 s.getComponentByPosition(0, instantiate=False) 

1910 

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

1912 # object and returns it 

1913 s.getComponentByPosition(0, instantiate=True) 

1914 

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

1916 s.setComponentByPosition(0, 'ABCD') 

1917 

1918 # returns OctetString('ABCD') value object 

1919 s.getComponentByPosition(0, instantiate=False) 

1920 

1921 s.clear() 

1922 

1923 # returns noValue 

1924 s.getComponentByPosition(0, instantiate=False) 

1925 """ 

1926 if isinstance(idx, slice): 

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

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

1929 for subidx in indices[idx]] 

1930 

1931 if idx < 0: 

1932 idx = len(self) + idx 

1933 if idx < 0: 

1934 raise error.PyAsn1Error( 

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

1936 

1937 try: 

1938 componentValue = self._componentValues[idx] 

1939 

1940 except (KeyError, error.PyAsn1Error): 

1941 if not instantiate: 

1942 return default 

1943 

1944 self.setComponentByPosition(idx) 

1945 

1946 componentValue = self._componentValues[idx] 

1947 

1948 if default is noValue or componentValue.isValue: 

1949 return componentValue 

1950 else: 

1951 return default 

1952 

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

1954 verifyConstraints=True, 

1955 matchTags=True, 

1956 matchConstraints=True): 

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

1958 

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

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

1961 

1962 Parameters 

1963 ---------- 

1964 idx: :class:`int` 

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

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

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

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

1969 

1970 Keyword Args 

1971 ------------ 

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

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

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

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

1976 

1977 verifyConstraints: :class:`bool` 

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

1979 

1980 matchTags: :class:`bool` 

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

1982 

1983 matchConstraints: :class:`bool` 

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

1985 

1986 Returns 

1987 ------- 

1988 self 

1989 

1990 Raises 

1991 ------ 

1992 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

1993 On constraint violation or bad initializer 

1994 IndexError 

1995 When idx > len(self) 

1996 """ 

1997 if isinstance(idx, slice): 

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

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

2000 for subIdx, subValue in enumerate(value): 

2001 self.setComponentByPosition( 

2002 startIdx + subIdx, subValue, verifyConstraints, 

2003 matchTags, matchConstraints) 

2004 return self 

2005 

2006 if idx < 0: 

2007 idx = len(self) + idx 

2008 if idx < 0: 

2009 raise error.PyAsn1Error( 

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

2011 

2012 componentType = self.componentType 

2013 

2014 if self._componentValues is noValue: 

2015 componentValues = {} 

2016 

2017 else: 

2018 componentValues = self._componentValues 

2019 

2020 currentValue = componentValues.get(idx, noValue) 

2021 

2022 if value is noValue: 

2023 if componentType is not None: 

2024 value = componentType.clone() 

2025 

2026 elif currentValue is noValue: 

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

2028 

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

2030 if (componentType is not None and 

2031 isinstance(componentType, base.SimpleAsn1Type)): 

2032 value = componentType.clone(value=value) 

2033 

2034 elif (currentValue is not noValue and 

2035 isinstance(currentValue, base.SimpleAsn1Type)): 

2036 value = currentValue.clone(value=value) 

2037 

2038 else: 

2039 raise error.PyAsn1Error( 

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

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

2042 

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

2044 subtypeChecker = ( 

2045 self.strictConstraints and 

2046 componentType.isSameTypeWith or 

2047 componentType.isSuperTypeOf) 

2048 

2049 if not subtypeChecker(value, verifyConstraints and matchTags, 

2050 verifyConstraints and matchConstraints): 

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

2052 # additional properties associated with componentType 

2053 if componentType.typeId != Any.typeId: 

2054 raise error.PyAsn1Error( 

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

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

2057 

2058 componentValues[idx] = value 

2059 

2060 self._componentValues = componentValues 

2061 

2062 return self 

2063 

2064 @property 

2065 def componentTagMap(self): 

2066 if self.componentType is not None: 

2067 return self.componentType.tagMap 

2068 

2069 @property 

2070 def components(self): 

2071 return [self._componentValues[idx] 

2072 for idx in sorted(self._componentValues)] 

2073 

2074 def clear(self): 

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

2076 

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

2078 built-in. 

2079 """ 

2080 self._componentValues = {} 

2081 return self 

2082 

2083 def reset(self): 

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

2085 

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

2087 distinction between value and schema objects. 

2088 """ 

2089 self._componentValues = noValue 

2090 return self 

2091 

2092 def prettyPrint(self, scope=0): 

2093 scope += 1 

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

2095 

2096 if not self.isValue: 

2097 return representation 

2098 

2099 for idx, componentValue in enumerate(self): 

2100 representation += ' ' * scope 

2101 if (componentValue is noValue and 

2102 self.componentType is not None): 

2103 representation += '<empty>' 

2104 else: 

2105 representation += componentValue.prettyPrint(scope) 

2106 

2107 return representation 

2108 

2109 def prettyPrintType(self, scope=0): 

2110 scope += 1 

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

2112 if self.componentType is not None: 

2113 representation += ' ' * scope 

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

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

2116 

2117 

2118 @property 

2119 def isValue(self): 

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

2121 

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

2123 

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

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

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

2127 

2128 Returns 

2129 ------- 

2130 : :class:`bool` 

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

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

2133 

2134 Note 

2135 ---- 

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

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

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

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

2140 encoding/decoding serialised ASN.1 contents. 

2141 

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

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

2144 """ 

2145 if self._componentValues is noValue: 

2146 return False 

2147 

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

2149 return False 

2150 

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

2152 if componentValue is noValue or not componentValue.isValue: 

2153 return False 

2154 

2155 return True 

2156 

2157 @property 

2158 def isInconsistent(self): 

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

2160 

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

2162 by `subtypeSpec`. 

2163 

2164 Raises 

2165 ------ 

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

2167 """ 

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

2169 return False 

2170 

2171 if self._componentValues is noValue: 

2172 return True 

2173 

2174 mapping = {} 

2175 

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

2177 # Absent fields are not in the mapping 

2178 if value is noValue: 

2179 continue 

2180 

2181 mapping[idx] = value 

2182 

2183 try: 

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

2185 self.subtypeSpec(mapping) 

2186 

2187 except error.PyAsn1Error: 

2188 exc = sys.exc_info()[1] 

2189 return exc 

2190 

2191 return False 

2192 

2193class SequenceOf(SequenceOfAndSetOfBase): 

2194 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2195 

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

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

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

2199 tagSet = tag.initTagSet( 

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

2201 ) 

2202 

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

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

2205 componentType = None 

2206 

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

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

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

2210 subtypeSpec = constraint.ConstraintsIntersection() 

2211 

2212 # Disambiguation ASN.1 types identification 

2213 typeId = SequenceOfAndSetOfBase.getTypeId() 

2214 

2215 

2216class SetOf(SequenceOfAndSetOfBase): 

2217 __doc__ = SequenceOfAndSetOfBase.__doc__ 

2218 

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

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

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

2222 tagSet = tag.initTagSet( 

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

2224 ) 

2225 

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

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

2228 componentType = None 

2229 

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

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

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

2233 subtypeSpec = constraint.ConstraintsIntersection() 

2234 

2235 # Disambiguation ASN.1 types identification 

2236 typeId = SequenceOfAndSetOfBase.getTypeId() 

2237 

2238 

2239class SequenceAndSetBase(base.ConstructedAsn1Type): 

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

2241 

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

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

2244 

2245 Keyword Args 

2246 ------------ 

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

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

2249 

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

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

2252 

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

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

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

2256 `.isInconsistent` call. 

2257 

2258 Examples 

2259 -------- 

2260 

2261 .. code-block:: python 

2262 

2263 class Description(Sequence): # Set is similar 

2264 ''' 

2265 ASN.1 specification: 

2266 

2267 Description ::= SEQUENCE { 

2268 surname IA5String, 

2269 first-name IA5String OPTIONAL, 

2270 age INTEGER DEFAULT 40 

2271 } 

2272 ''' 

2273 componentType = NamedTypes( 

2274 NamedType('surname', IA5String()), 

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

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

2277 ) 

2278 

2279 descr = Description() 

2280 descr['surname'] = 'Smith' 

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

2282 """ 

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

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

2285 componentType = namedtype.NamedTypes() 

2286 

2287 

2288 class DynamicNames(object): 

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

2290 def __init__(self): 

2291 self._keyToIdxMap = {} 

2292 self._idxToKeyMap = {} 

2293 

2294 def __len__(self): 

2295 return len(self._keyToIdxMap) 

2296 

2297 def __contains__(self, item): 

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

2299 

2300 def __iter__(self): 

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

2302 

2303 def __getitem__(self, item): 

2304 try: 

2305 return self._keyToIdxMap[item] 

2306 

2307 except KeyError: 

2308 return self._idxToKeyMap[item] 

2309 

2310 def getNameByPosition(self, idx): 

2311 try: 

2312 return self._idxToKeyMap[idx] 

2313 

2314 except KeyError: 

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

2316 

2317 def getPositionByName(self, name): 

2318 try: 

2319 return self._keyToIdxMap[name] 

2320 

2321 except KeyError: 

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

2323 

2324 def addField(self, idx): 

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

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

2327 

2328 

2329 def __init__(self, **kwargs): 

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

2331 self._componentTypeLen = len(self.componentType) 

2332 if self._componentTypeLen: 

2333 self._componentValues = [] 

2334 else: 

2335 self._componentValues = noValue 

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

2337 

2338 def __getitem__(self, idx): 

2339 if octets.isStringType(idx): 

2340 try: 

2341 return self.getComponentByName(idx) 

2342 

2343 except error.PyAsn1Error: 

2344 # duck-typing dict 

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

2346 

2347 else: 

2348 try: 

2349 return self.getComponentByPosition(idx) 

2350 

2351 except error.PyAsn1Error: 

2352 # duck-typing list 

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

2354 

2355 def __setitem__(self, idx, value): 

2356 if octets.isStringType(idx): 

2357 try: 

2358 self.setComponentByName(idx, value) 

2359 

2360 except error.PyAsn1Error: 

2361 # duck-typing dict 

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

2363 

2364 else: 

2365 try: 

2366 self.setComponentByPosition(idx, value) 

2367 

2368 except error.PyAsn1Error: 

2369 # duck-typing list 

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

2371 

2372 def __contains__(self, key): 

2373 if self._componentTypeLen: 

2374 return key in self.componentType 

2375 else: 

2376 return key in self._dynamicNames 

2377 

2378 def __len__(self): 

2379 return len(self._componentValues) 

2380 

2381 def __iter__(self): 

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

2383 

2384 # Python dict protocol 

2385 

2386 def values(self): 

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

2388 yield self[idx] 

2389 

2390 def keys(self): 

2391 return iter(self) 

2392 

2393 def items(self): 

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

2395 if self._componentTypeLen: 

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

2397 else: 

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

2399 

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

2401 for k, v in iterValue: 

2402 self[k] = v 

2403 for k in mappingValue: 

2404 self[k] = mappingValue[k] 

2405 

2406 def clear(self): 

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

2408 

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

2410 built-in. 

2411 """ 

2412 self._componentValues = [] 

2413 self._dynamicNames = self.DynamicNames() 

2414 return self 

2415 

2416 def reset(self): 

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

2418 

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

2420 distinction between value and schema objects. 

2421 """ 

2422 self._componentValues = noValue 

2423 self._dynamicNames = self.DynamicNames() 

2424 return self 

2425 

2426 @property 

2427 def components(self): 

2428 return self._componentValues 

2429 

2430 def _cloneComponentValues(self, myClone, cloneValueFlag): 

2431 if self._componentValues is noValue: 

2432 return 

2433 

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

2435 if componentValue is not noValue: 

2436 if isinstance(componentValue, base.ConstructedAsn1Type): 

2437 myClone.setComponentByPosition( 

2438 idx, componentValue.clone(cloneValueFlag=cloneValueFlag) 

2439 ) 

2440 else: 

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

2442 

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

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

2445 

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

2447 

2448 Parameters 

2449 ---------- 

2450 name: :class:`str` 

2451 |ASN.1| type component name 

2452 

2453 Keyword Args 

2454 ------------ 

2455 default: :class:`object` 

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

2457 object instead of the requested component. 

2458 

2459 instantiate: :class:`bool` 

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

2461 instantiated. 

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

2463 object will be returned. 

2464 

2465 Returns 

2466 ------- 

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

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

2469 component value 

2470 """ 

2471 if self._componentTypeLen: 

2472 idx = self.componentType.getPositionByName(name) 

2473 else: 

2474 try: 

2475 idx = self._dynamicNames.getPositionByName(name) 

2476 

2477 except KeyError: 

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

2479 

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

2481 

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

2483 verifyConstraints=True, 

2484 matchTags=True, 

2485 matchConstraints=True): 

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

2487 

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

2489 

2490 Parameters 

2491 ---------- 

2492 name: :class:`str` 

2493 |ASN.1| type component name 

2494 

2495 Keyword Args 

2496 ------------ 

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

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

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

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

2501 

2502 verifyConstraints: :class:`bool` 

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

2504 

2505 matchTags: :class:`bool` 

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

2507 

2508 matchConstraints: :class:`bool` 

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

2510 

2511 Returns 

2512 ------- 

2513 self 

2514 """ 

2515 if self._componentTypeLen: 

2516 idx = self.componentType.getPositionByName(name) 

2517 else: 

2518 try: 

2519 idx = self._dynamicNames.getPositionByName(name) 

2520 

2521 except KeyError: 

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

2523 

2524 return self.setComponentByPosition( 

2525 idx, value, verifyConstraints, matchTags, matchConstraints 

2526 ) 

2527 

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

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

2530 

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

2532 

2533 Parameters 

2534 ---------- 

2535 idx: :class:`int` 

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

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

2538 instantiated. 

2539 

2540 Keyword Args 

2541 ------------ 

2542 default: :class:`object` 

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

2544 object instead of the requested component. 

2545 

2546 instantiate: :class:`bool` 

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

2548 instantiated. 

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

2550 object will be returned. 

2551 

2552 Returns 

2553 ------- 

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

2555 a PyASN1 object 

2556 

2557 Examples 

2558 -------- 

2559 

2560 .. code-block:: python 

2561 

2562 # can also be Set 

2563 class MySequence(Sequence): 

2564 componentType = NamedTypes( 

2565 NamedType('id', OctetString()) 

2566 ) 

2567 

2568 s = MySequence() 

2569 

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

2571 s.getComponentByPosition(0) 

2572 

2573 # returns None 

2574 s.getComponentByPosition(0, default=None) 

2575 

2576 s.clear() 

2577 

2578 # returns noValue 

2579 s.getComponentByPosition(0, instantiate=False) 

2580 

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

2582 # object and returns it 

2583 s.getComponentByPosition(0, instantiate=True) 

2584 

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

2586 s.setComponentByPosition(0, 'ABCD') 

2587 

2588 # returns OctetString('ABCD') value object 

2589 s.getComponentByPosition(0, instantiate=False) 

2590 

2591 s.clear() 

2592 

2593 # returns noValue 

2594 s.getComponentByPosition(0, instantiate=False) 

2595 """ 

2596 try: 

2597 if self._componentValues is noValue: 

2598 componentValue = noValue 

2599 

2600 else: 

2601 componentValue = self._componentValues[idx] 

2602 

2603 except IndexError: 

2604 componentValue = noValue 

2605 

2606 if not instantiate: 

2607 if componentValue is noValue or not componentValue.isValue: 

2608 return default 

2609 else: 

2610 return componentValue 

2611 

2612 if componentValue is noValue: 

2613 self.setComponentByPosition(idx) 

2614 

2615 componentValue = self._componentValues[idx] 

2616 

2617 if default is noValue or componentValue.isValue: 

2618 return componentValue 

2619 else: 

2620 return default 

2621 

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

2623 verifyConstraints=True, 

2624 matchTags=True, 

2625 matchConstraints=True): 

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

2627 

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

2629 

2630 Parameters 

2631 ---------- 

2632 idx : :class:`int` 

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

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

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

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

2637 

2638 Keyword Args 

2639 ------------ 

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

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

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

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

2644 

2645 verifyConstraints : :class:`bool` 

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

2647 

2648 matchTags: :class:`bool` 

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

2650 

2651 matchConstraints: :class:`bool` 

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

2653 

2654 Returns 

2655 ------- 

2656 self 

2657 """ 

2658 componentType = self.componentType 

2659 componentTypeLen = self._componentTypeLen 

2660 

2661 if self._componentValues is noValue: 

2662 componentValues = [] 

2663 

2664 else: 

2665 componentValues = self._componentValues 

2666 

2667 try: 

2668 currentValue = componentValues[idx] 

2669 

2670 except IndexError: 

2671 currentValue = noValue 

2672 if componentTypeLen: 

2673 if componentTypeLen < idx: 

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

2675 

2676 componentValues = [noValue] * componentTypeLen 

2677 

2678 if value is noValue: 

2679 if componentTypeLen: 

2680 value = componentType.getTypeByPosition(idx) 

2681 if isinstance(value, base.ConstructedAsn1Type): 

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

2683 

2684 elif currentValue is noValue: 

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

2686 

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

2688 if componentTypeLen: 

2689 subComponentType = componentType.getTypeByPosition(idx) 

2690 if isinstance(subComponentType, base.SimpleAsn1Type): 

2691 value = subComponentType.clone(value=value) 

2692 

2693 else: 

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

2695 

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

2697 value = currentValue.clone(value=value) 

2698 

2699 else: 

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

2701 

2702 elif ((verifyConstraints or matchTags or matchConstraints) and 

2703 componentTypeLen): 

2704 subComponentType = componentType.getTypeByPosition(idx) 

2705 if subComponentType is not noValue: 

2706 subtypeChecker = (self.strictConstraints and 

2707 subComponentType.isSameTypeWith or 

2708 subComponentType.isSuperTypeOf) 

2709 

2710 if not subtypeChecker(value, verifyConstraints and matchTags, 

2711 verifyConstraints and matchConstraints): 

2712 if not componentType[idx].openType: 

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

2714 

2715 if componentTypeLen or idx in self._dynamicNames: 

2716 componentValues[idx] = value 

2717 

2718 elif len(componentValues) == idx: 

2719 componentValues.append(value) 

2720 self._dynamicNames.addField(idx) 

2721 

2722 else: 

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

2724 

2725 self._componentValues = componentValues 

2726 

2727 return self 

2728 

2729 @property 

2730 def isValue(self): 

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

2732 

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

2734 

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

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

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

2738 

2739 Returns 

2740 ------- 

2741 : :class:`bool` 

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

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

2744 normal value. 

2745 

2746 Note 

2747 ---- 

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

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

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

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

2752 encoding/decoding serialised ASN.1 contents. 

2753 

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

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

2756 

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

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

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

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

2761 components are normally value objects by default. 

2762 """ 

2763 if self._componentValues is noValue: 

2764 return False 

2765 

2766 componentType = self.componentType 

2767 

2768 if componentType: 

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

2770 if subComponentType.isDefaulted or subComponentType.isOptional: 

2771 continue 

2772 

2773 if not self._componentValues: 

2774 return False 

2775 

2776 componentValue = self._componentValues[idx] 

2777 if componentValue is noValue or not componentValue.isValue: 

2778 return False 

2779 

2780 else: 

2781 for componentValue in self._componentValues: 

2782 if componentValue is noValue or not componentValue.isValue: 

2783 return False 

2784 

2785 return True 

2786 

2787 @property 

2788 def isInconsistent(self): 

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

2790 

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

2792 by `subtypeSpec`. 

2793 

2794 Raises 

2795 ------ 

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

2797 """ 

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

2799 return False 

2800 

2801 if self._componentValues is noValue: 

2802 return True 

2803 

2804 mapping = {} 

2805 

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

2807 # Absent fields are not in the mapping 

2808 if value is noValue: 

2809 continue 

2810 

2811 name = self.componentType.getNameByPosition(idx) 

2812 

2813 mapping[name] = value 

2814 

2815 try: 

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

2817 self.subtypeSpec(mapping) 

2818 

2819 except error.PyAsn1Error: 

2820 exc = sys.exc_info()[1] 

2821 return exc 

2822 

2823 return False 

2824 

2825 def prettyPrint(self, scope=0): 

2826 """Return an object representation string. 

2827 

2828 Returns 

2829 ------- 

2830 : :class:`str` 

2831 Human-friendly object representation. 

2832 """ 

2833 scope += 1 

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

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

2836 if componentValue is not noValue and componentValue.isValue: 

2837 representation += ' ' * scope 

2838 if self.componentType: 

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

2840 else: 

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

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

2843 representation, componentValue.prettyPrint(scope) 

2844 ) 

2845 return representation 

2846 

2847 def prettyPrintType(self, scope=0): 

2848 scope += 1 

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

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

2851 representation += ' ' * scope 

2852 if self.componentType: 

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

2854 else: 

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

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

2857 representation, componentType.prettyPrintType(scope) 

2858 ) 

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

2860 

2861 # backward compatibility 

2862 

2863 def setDefaultComponents(self): 

2864 return self 

2865 

2866 def getComponentType(self): 

2867 if self._componentTypeLen: 

2868 return self.componentType 

2869 

2870 def getNameByPosition(self, idx): 

2871 if self._componentTypeLen: 

2872 return self.componentType[idx].name 

2873 

2874class Sequence(SequenceAndSetBase): 

2875 __doc__ = SequenceAndSetBase.__doc__ 

2876 

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

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

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

2880 tagSet = tag.initTagSet( 

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

2882 ) 

2883 

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

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

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

2887 subtypeSpec = constraint.ConstraintsIntersection() 

2888 

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

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

2891 componentType = namedtype.NamedTypes() 

2892 

2893 # Disambiguation ASN.1 types identification 

2894 typeId = SequenceAndSetBase.getTypeId() 

2895 

2896 # backward compatibility 

2897 

2898 def getComponentTagMapNearPosition(self, idx): 

2899 if self.componentType: 

2900 return self.componentType.getTagMapNearPosition(idx) 

2901 

2902 def getComponentPositionNearType(self, tagSet, idx): 

2903 if self.componentType: 

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

2905 else: 

2906 return idx 

2907 

2908 

2909class Set(SequenceAndSetBase): 

2910 __doc__ = SequenceAndSetBase.__doc__ 

2911 

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

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

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

2915 tagSet = tag.initTagSet( 

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

2917 ) 

2918 

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

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

2921 componentType = namedtype.NamedTypes() 

2922 

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

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

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

2926 subtypeSpec = constraint.ConstraintsIntersection() 

2927 

2928 # Disambiguation ASN.1 types identification 

2929 typeId = SequenceAndSetBase.getTypeId() 

2930 

2931 def getComponent(self, innerFlag=False): 

2932 return self 

2933 

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

2935 instantiate=True, innerFlag=False): 

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

2937 

2938 Parameters 

2939 ---------- 

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

2941 Object representing ASN.1 tags to identify one of 

2942 |ASN.1| object component 

2943 

2944 Keyword Args 

2945 ------------ 

2946 default: :class:`object` 

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

2948 object instead of the requested component. 

2949 

2950 instantiate: :class:`bool` 

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

2952 instantiated. 

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

2954 object will be returned. 

2955 

2956 Returns 

2957 ------- 

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

2959 a pyasn1 object 

2960 """ 

2961 componentValue = self.getComponentByPosition( 

2962 self.componentType.getPositionByType(tagSet), 

2963 default=default, instantiate=instantiate 

2964 ) 

2965 if innerFlag and isinstance(componentValue, Set): 

2966 # get inner component by inner tagSet 

2967 return componentValue.getComponent(innerFlag=True) 

2968 else: 

2969 # get outer component by inner tagSet 

2970 return componentValue 

2971 

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

2973 verifyConstraints=True, 

2974 matchTags=True, 

2975 matchConstraints=True, 

2976 innerFlag=False): 

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

2978 

2979 Parameters 

2980 ---------- 

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

2982 Object representing ASN.1 tags to identify one of 

2983 |ASN.1| object component 

2984 

2985 Keyword Args 

2986 ------------ 

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

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

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

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

2991 

2992 verifyConstraints : :class:`bool` 

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

2994 

2995 matchTags: :class:`bool` 

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

2997 

2998 matchConstraints: :class:`bool` 

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

3000 

3001 innerFlag: :class:`bool` 

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

3003 

3004 Returns 

3005 ------- 

3006 self 

3007 """ 

3008 idx = self.componentType.getPositionByType(tagSet) 

3009 

3010 if innerFlag: # set inner component by inner tagSet 

3011 componentType = self.componentType.getTypeByPosition(idx) 

3012 

3013 if componentType.tagSet: 

3014 return self.setComponentByPosition( 

3015 idx, value, verifyConstraints, matchTags, matchConstraints 

3016 ) 

3017 else: 

3018 componentType = self.getComponentByPosition(idx) 

3019 return componentType.setComponentByType( 

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

3021 ) 

3022 else: # set outer component by inner tagSet 

3023 return self.setComponentByPosition( 

3024 idx, value, verifyConstraints, matchTags, matchConstraints 

3025 ) 

3026 

3027 @property 

3028 def componentTagMap(self): 

3029 if self.componentType: 

3030 return self.componentType.tagMapUnique 

3031 

3032 

3033class Choice(Set): 

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

3035 

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

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

3038 

3039 Keyword Args 

3040 ------------ 

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

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

3043 

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

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

3046 

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

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

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

3050 `.isInconsistent` call. 

3051 

3052 Examples 

3053 -------- 

3054 

3055 .. code-block:: python 

3056 

3057 class Afters(Choice): 

3058 ''' 

3059 ASN.1 specification: 

3060 

3061 Afters ::= CHOICE { 

3062 cheese [0] IA5String, 

3063 dessert [1] IA5String 

3064 } 

3065 ''' 

3066 componentType = NamedTypes( 

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

3068 implicitTag=Tag(tagClassContext, tagFormatSimple, 0) 

3069 ), 

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

3071 implicitTag=Tag(tagClassContext, tagFormatSimple, 1) 

3072 ) 

3073 ) 

3074 

3075 afters = Afters() 

3076 afters['cheese'] = 'Mascarpone' 

3077 """ 

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

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

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

3081 tagSet = tag.TagSet() # untagged 

3082 

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

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

3085 componentType = namedtype.NamedTypes() 

3086 

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

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

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

3090 subtypeSpec = constraint.ConstraintsIntersection( 

3091 constraint.ValueSizeConstraint(1, 1) 

3092 ) 

3093 

3094 # Disambiguation ASN.1 types identification 

3095 typeId = Set.getTypeId() 

3096 

3097 _currentIdx = None 

3098 

3099 def __eq__(self, other): 

3100 if self._componentValues: 

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

3102 return NotImplemented 

3103 

3104 def __ne__(self, other): 

3105 if self._componentValues: 

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

3107 return NotImplemented 

3108 

3109 def __lt__(self, other): 

3110 if self._componentValues: 

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

3112 return NotImplemented 

3113 

3114 def __le__(self, other): 

3115 if self._componentValues: 

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

3117 return NotImplemented 

3118 

3119 def __gt__(self, other): 

3120 if self._componentValues: 

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

3122 return NotImplemented 

3123 

3124 def __ge__(self, other): 

3125 if self._componentValues: 

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

3127 return NotImplemented 

3128 

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

3130 def __nonzero__(self): 

3131 return self._componentValues and True or False 

3132 else: 

3133 def __bool__(self): 

3134 return self._componentValues and True or False 

3135 

3136 def __len__(self): 

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

3138 

3139 def __contains__(self, key): 

3140 if self._currentIdx is None: 

3141 return False 

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

3143 

3144 def __iter__(self): 

3145 if self._currentIdx is None: 

3146 raise StopIteration 

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

3148 

3149 # Python dict protocol 

3150 

3151 def values(self): 

3152 if self._currentIdx is not None: 

3153 yield self._componentValues[self._currentIdx] 

3154 

3155 def keys(self): 

3156 if self._currentIdx is not None: 

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

3158 

3159 def items(self): 

3160 if self._currentIdx is not None: 

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

3162 

3163 def checkConsistency(self): 

3164 if self._currentIdx is None: 

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

3166 

3167 def _cloneComponentValues(self, myClone, cloneValueFlag): 

3168 try: 

3169 component = self.getComponent() 

3170 except error.PyAsn1Error: 

3171 pass 

3172 else: 

3173 if isinstance(component, Choice): 

3174 tagSet = component.effectiveTagSet 

3175 else: 

3176 tagSet = component.tagSet 

3177 if isinstance(component, base.ConstructedAsn1Type): 

3178 myClone.setComponentByType( 

3179 tagSet, component.clone(cloneValueFlag=cloneValueFlag) 

3180 ) 

3181 else: 

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

3183 

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

3185 __doc__ = Set.__doc__ 

3186 

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

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

3189 instantiate=instantiate) 

3190 

3191 return self._componentValues[idx] 

3192 

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

3194 verifyConstraints=True, 

3195 matchTags=True, 

3196 matchConstraints=True): 

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

3198 

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

3200 

3201 Parameters 

3202 ---------- 

3203 idx: :class:`int` 

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

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

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

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

3208 

3209 Keyword Args 

3210 ------------ 

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

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

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

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

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

3216 

3217 verifyConstraints : :class:`bool` 

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

3219 

3220 matchTags: :class:`bool` 

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

3222 

3223 matchConstraints: :class:`bool` 

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

3225 

3226 Returns 

3227 ------- 

3228 self 

3229 """ 

3230 oldIdx = self._currentIdx 

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

3232 self._currentIdx = idx 

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

3234 self._componentValues[oldIdx] = noValue 

3235 return self 

3236 

3237 @property 

3238 def effectiveTagSet(self): 

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

3240 if self.tagSet: 

3241 return self.tagSet 

3242 else: 

3243 component = self.getComponent() 

3244 return component.effectiveTagSet 

3245 

3246 @property 

3247 def tagMap(self): 

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

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

3250 """ 

3251 if self.tagSet: 

3252 return Set.tagMap.fget(self) 

3253 else: 

3254 return self.componentType.tagMapUnique 

3255 

3256 def getComponent(self, innerFlag=False): 

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

3258 

3259 Returns 

3260 ------- 

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

3262 a PyASN1 object 

3263 """ 

3264 if self._currentIdx is None: 

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

3266 else: 

3267 c = self._componentValues[self._currentIdx] 

3268 if innerFlag and isinstance(c, Choice): 

3269 return c.getComponent(innerFlag) 

3270 else: 

3271 return c 

3272 

3273 def getName(self, innerFlag=False): 

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

3275 

3276 Returns 

3277 ------- 

3278 : :py:class:`str` 

3279 |ASN.1| component name 

3280 """ 

3281 if self._currentIdx is None: 

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

3283 else: 

3284 if innerFlag: 

3285 c = self._componentValues[self._currentIdx] 

3286 if isinstance(c, Choice): 

3287 return c.getName(innerFlag) 

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

3289 

3290 @property 

3291 def isValue(self): 

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

3293 

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

3295 

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

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

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

3299 

3300 Returns 

3301 ------- 

3302 : :class:`bool` 

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

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

3305 value. 

3306 

3307 Note 

3308 ---- 

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

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

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

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

3313 encoding/decoding serialised ASN.1 contents. 

3314 

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

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

3317 """ 

3318 if self._currentIdx is None: 

3319 return False 

3320 

3321 componentValue = self._componentValues[self._currentIdx] 

3322 

3323 return componentValue is not noValue and componentValue.isValue 

3324 

3325 def clear(self): 

3326 self._currentIdx = None 

3327 return Set.clear(self) 

3328 

3329 # compatibility stubs 

3330 

3331 def getMinTagSet(self): 

3332 return self.minTagSet 

3333 

3334 

3335class Any(OctetString): 

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

3337 

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

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

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

3341 "|encoding|" serialisation. 

3342 

3343 Keyword Args 

3344 ------------ 

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

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

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

3348 representing character string to be serialised into octets (note 

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

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

3351 

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

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

3354 

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

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

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

3358 instantiation. 

3359 

3360 encoding: :py:class:`str` 

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

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

3363 in text string context. 

3364 

3365 binValue: :py:class:`str` 

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

3367 Example: '10110011'. 

3368 

3369 hexValue: :py:class:`str` 

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

3371 Example: 'DEADBEEF'. 

3372 

3373 Raises 

3374 ------ 

3375 ~pyasn1.error.ValueConstraintError, ~pyasn1.error.PyAsn1Error 

3376 On constraint violation or bad initializer. 

3377 

3378 Examples 

3379 -------- 

3380 .. code-block:: python 

3381 

3382 class Error(Sequence): 

3383 ''' 

3384 ASN.1 specification: 

3385 

3386 Error ::= SEQUENCE { 

3387 code INTEGER, 

3388 parameter ANY DEFINED BY code -- Either INTEGER or REAL 

3389 } 

3390 ''' 

3391 componentType=NamedTypes( 

3392 NamedType('code', Integer()), 

3393 NamedType('parameter', Any(), 

3394 openType=OpenType('code', {1: Integer(), 

3395 2: Real()})) 

3396 ) 

3397 

3398 error = Error() 

3399 error['code'] = 1 

3400 error['parameter'] = Integer(1234) 

3401 """ 

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

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

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

3405 tagSet = tag.TagSet() # untagged 

3406 

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

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

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

3410 subtypeSpec = constraint.ConstraintsIntersection() 

3411 

3412 # Disambiguation ASN.1 types identification 

3413 typeId = OctetString.getTypeId() 

3414 

3415 @property 

3416 def tagMap(self): 

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

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

3419 """ 

3420 try: 

3421 return self._tagMap 

3422 

3423 except AttributeError: 

3424 self._tagMap = tagmap.TagMap( 

3425 {self.tagSet: self}, 

3426 {eoo.endOfOctets.tagSet: eoo.endOfOctets}, 

3427 self 

3428 ) 

3429 

3430 return self._tagMap 

3431 

3432# XXX 

3433# coercion rules?