]> Cypherpunks.ru repositories - pyderasn.git/blobdiff - pyderasn.py
Integer.tohex()
[pyderasn.git] / pyderasn.py
index 62e884ba9357bfc49f21f77c19c7cd90fe21f954..162c1404a3af15ddbae345c63d391f8d34fb45e2 100755 (executable)
@@ -665,6 +665,11 @@ parse the CRL above with fully assembled ``RevokedCertificate``::
         ):
             print("serial number:", int(obj["userCertificate"]))
 
+.. note::
+
+   SEQUENCE/SET values with DEFAULT specified are automatically decoded
+   without evgen mode.
+
 .. _mmap:
 
 mmap-ed file
@@ -912,7 +917,7 @@ _______
 Integer
 _______
 .. autoclass:: pyderasn.Integer
-   :members: __init__, named
+   :members: __init__, named, tohex
 
 BitString
 _________
@@ -1180,7 +1185,7 @@ except ImportError:  # pragma: no cover
     def colored(what, *args, **kwargs):
         return what
 
-__version__ = "7.2"
+__version__ = "7.4"
 
 __all__ = (
     "agg_octet_string",
@@ -1190,6 +1195,7 @@ __all__ = (
     "Boolean",
     "BoundsError",
     "Choice",
+    "colonize_hex",
     "DecodeError",
     "DecodePathDefBy",
     "encode2pass",
@@ -2372,13 +2378,8 @@ def pp_console_row(
                     cols.append(_colourize("(%s)" % oid_name, "green", with_colours))
                     break
         if pp.asn1_type_name == Integer.asn1_type_name:
-            hex_repr = hex(int(pp.obj._value))[2:].upper()
-            if len(hex_repr) % 2 != 0:
-                hex_repr = "0" + hex_repr
             cols.append(_colourize(
-                "(%s)" % colonize_hex(hex_repr),
-                "green",
-                with_colours,
+                "(%s)" % colonize_hex(pp.obj.tohex()), "green", with_colours,
             ))
     if with_blob:
         if pp.blob.__class__ == binary_type:
@@ -2845,6 +2846,16 @@ class Integer(Obj):
         self._assert_ready()
         return int(self._value)
 
+    def tohex(self):
+        """Hexadecimal representation
+
+        Use :py:func:`pyderasn.colonize_hex` for colonizing it.
+        """
+        hex_repr = hex(int(self))[2:].upper()
+        if len(hex_repr) % 2 != 0:
+            hex_repr = "0" + hex_repr
+        return hex_repr
+
     def __hash__(self):
         self._assert_ready()
         return hash(b"".join((
@@ -2936,7 +2947,6 @@ class Integer(Obj):
                 else:
                     break
         return octets
-        return b"".join((self.tag, len_encode(len(octets)), octets))
 
     def _encode(self):
         octets = self._encode_payload()
@@ -6195,11 +6205,10 @@ class Sequence(SequenceEncode1stMixing, Obj):
     defaulted values existence validation by setting
     ``"allow_default_values": True`` :ref:`context <ctx>` option.
 
-    .. warning::
-
-       Check for default value existence is not performed in
-       ``evgen_mode``, because previously decoded values are not stored
-       in memory, to be able to compare them.
+    All values with DEFAULT specified are decoded atomically in
+    :ref:`evgen mode <evgen_mode>`. If DEFAULT value is some kind of
+    SEQUENCE, then it will be yielded as a single element, not
+    disassembled. That is required for DEFAULT existence check.
 
     Two sequences are equal if they have equal specification (schema),
     implicit/explicit tagging and the same values.
@@ -6425,9 +6434,10 @@ class Sequence(SequenceEncode1stMixing, Obj):
                     len(v) == 0
             ):
                 continue
+            spec_defaulted = spec.default is not None
             sub_decode_path = decode_path + (name,)
             try:
-                if evgen_mode:
+                if evgen_mode and not spec_defaulted:
                     for _decode_path, value, v_tail in spec.decode_evgen(
                             v,
                             sub_offset,
@@ -6505,9 +6515,10 @@ class Sequence(SequenceEncode1stMixing, Obj):
             vlen += value_len
             sub_offset += value_len
             v = v_tail
-            if not evgen_mode:
-                if spec.default is not None and value == spec.default:
-                    # This will not work in evgen_mode
+            if spec_defaulted:
+                if evgen_mode:
+                    yield sub_decode_path, value, v_tail
+                if value == spec.default:
                     if ctx_bered or ctx_allow_default_values:
                         ber_encoded = True
                     else:
@@ -6517,6 +6528,7 @@ class Sequence(SequenceEncode1stMixing, Obj):
                             decode_path=sub_decode_path,
                             offset=sub_offset,
                         )
+            if not evgen_mode:
                 values[name] = value
                 spec_defines = getattr(spec, "defines", ())
                 if len(spec_defines) == 0:
@@ -6716,7 +6728,8 @@ class Set(Sequence, SequenceEncode1stMixing):
                     decode_path=decode_path,
                     offset=offset,
                 )
-            if evgen_mode:
+            spec_defaulted = spec.default is not None
+            if evgen_mode and not spec_defaulted:
                 for _decode_path, value, v_tail in spec.decode_evgen(
                         v,
                         sub_offset,
@@ -6748,17 +6761,20 @@ class Set(Sequence, SequenceEncode1stMixing):
                         decode_path=sub_decode_path,
                         offset=sub_offset,
                     )
-            if spec.default is None or value != spec.default:
-                pass
-            elif ctx_bered or ctx_allow_default_values:
-                ber_encoded = True
-            else:
-                raise DecodeError(
-                    "DEFAULT value met",
-                    klass=self.__class__,
-                    decode_path=sub_decode_path,
-                    offset=sub_offset,
-                )
+            if spec_defaulted:
+                if evgen_mode:
+                    yield sub_decode_path, value, v_tail
+                if value != spec.default:
+                    pass
+                elif ctx_bered or ctx_allow_default_values:
+                    ber_encoded = True
+                else:
+                    raise DecodeError(
+                        "DEFAULT value met",
+                        klass=self.__class__,
+                        decode_path=sub_decode_path,
+                        offset=sub_offset,
+                    )
             values[name] = value
             del _specs_items[name]
             tag_order_prev = value_tag_order
@@ -7483,4 +7499,5 @@ def main():  # pragma: no cover
 
 
 if __name__ == "__main__":
+    from pyderasn import *
     main()