| 293 | |
| 294 | |
| 295 | class ObjectIdentifierEncoder(AbstractItemEncoder): |
| 296 | supportIndefLenMode = False |
| 297 | |
| 298 | def encodeValue(self, value, asn1Spec, encodeFun, **options): |
| 299 | if asn1Spec is not None: |
| 300 | value = asn1Spec.clone(value) |
| 301 | |
| 302 | oid = value.asTuple() |
| 303 | |
| 304 | # Build the first pair |
| 305 | try: |
| 306 | first = oid[0] |
| 307 | second = oid[1] |
| 308 | |
| 309 | except IndexError: |
| 310 | raise error.PyAsn1Error('Short OID %s' % (value,)) |
| 311 | |
| 312 | if 0 <= second <= 39: |
| 313 | if first == 1: |
| 314 | oid = (second + 40,) + oid[2:] |
| 315 | elif first == 0: |
| 316 | oid = (second,) + oid[2:] |
| 317 | elif first == 2: |
| 318 | oid = (second + 80,) + oid[2:] |
| 319 | else: |
| 320 | raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) |
| 321 | |
| 322 | elif first == 2: |
| 323 | oid = (second + 80,) + oid[2:] |
| 324 | |
| 325 | else: |
| 326 | raise error.PyAsn1Error('Impossible first/second arcs at %s' % (value,)) |
| 327 | |
| 328 | octets = () |
| 329 | |
| 330 | # Cycle through subIds |
| 331 | for subOid in oid: |
| 332 | if 0 <= subOid <= 127: |
| 333 | # Optimize for the common case |
| 334 | octets += (subOid,) |
| 335 | |
| 336 | elif subOid > 127: |
| 337 | # Pack large Sub-Object IDs |
| 338 | res = (subOid & 0x7f,) |
| 339 | subOid >>= 7 |
| 340 | |
| 341 | while subOid: |
| 342 | res = (0x80 | (subOid & 0x7f),) + res |
| 343 | subOid >>= 7 |
| 344 | |
| 345 | # Add packed Sub-Object ID to resulted Object ID |
| 346 | octets += res |
| 347 | |
| 348 | else: |
| 349 | raise error.PyAsn1Error('Negative OID arc %s at %s' % (subOid, value)) |
| 350 | |
| 351 | return octets, False, False |
| 352 | |