11import binascii
2+ import re
23
3- from ...spec .structures .interface_types import TPMI_ST_COMMAND_TAG
44from ..binary import Binary
55from ..hex import Hex
66from ..pcapng import Pcapng
77
88
9- def detect_format_and_yield_buffer (buffer ):
9+ def detect_format_and_yield_buffer (buffer , strict = True ):
1010 """First yield is format. Rest is buffer bytewise."""
1111 buffer_iter = iter (buffer )
1212
@@ -19,26 +19,29 @@ def detect_format_and_yield_buffer(buffer):
1919 ) from e
2020
2121 if look_ahead == b"\x0a \x0d " :
22- # TODO use enum or some sort of canonical mapping?
2322 yield "pcapng"
24- elif look_ahead == b"80" :
25- yield "hex"
26- elif look_ahead in (
27- tag .to_bytes () for tag in TPMI_ST_COMMAND_TAG ._valid_values ._values
28- ):
29- yield "binary"
3023 else :
31- raise IOError (
32- f"Unknown detect input format: magic number is { binascii .hexlify (look_ahead ).decode ()} "
33- )
24+ if re .match (b"[0-9a-fA-F]{2}" , look_ahead ):
25+ # look ahead is valid hex, so it's MAYBE hex
26+ if not strict :
27+ yield "hex"
28+ else :
29+ raise IOError (
30+ f"Ambiguous input format: magic number is { binascii .hexlify (look_ahead ).decode ()} . Could be binary or hex."
31+ )
32+ else :
33+ # not valid hex, so it must be binary
34+ yield "binary"
3435
3536 yield from look_ahead
3637 yield from buffer_iter
3738
3839
39- def marshal (tpm_type , buffer , root_path = None , command_code = None , ** kwargs ):
40+ def marshal (
41+ tpm_type , buffer , root_path = None , command_code = None , strict = False , ** kwargs
42+ ):
4043 """Generator. Take iterable which yields single bytes. Yield MarshalEvents. Be smart about format."""
41- format_buffer_iter = detect_format_and_yield_buffer (buffer )
44+ format_buffer_iter = detect_format_and_yield_buffer (buffer , strict = strict )
4245
4346 format = next (format_buffer_iter )
4447
0 commit comments