Decode a trail of <<Header, Length, Payload, ......, Header, Length, Payload,.......>> from Binary Input

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Tue Jul 14 23:48:32 CEST 2020


On Tue, Jul 14, 2020 at 10:57 PM Oliver Korpilla <Oliver.Korpilla@REDACTED>
wrote:

>
> extract(<< >>) -> [];
> extract(<< Header:8, X/binary>>) ->
>   Bits    = Header * 8,
>   << Length:Bits, Y/binary >> = X,
>   Payload = binary:part(Y, 0, Length),
>   Rest    = binary:part(Y, Length, byte_size(Y) - Length),
>   Result  = { Header, Length, Payload },
>   [ Result | extract(Rest) ].
>

You can match directly on the length, which simplifies it a bit:

decode(<<Header:8, X/binary>>) ->
    L = Header*8,
    <<Length:L/integer, Payload:Length/binary, Rest/binary>> = X,
    [{Header, Length, Payload} | decode(Rest)];
decode(<<>>) ->
    [].

You avoid having to mangle with binary:part/3. However, if there are only 4
headers, the following is also quite readable:

decode(<<1, L:8/integer, Payload:L/binary, Rest/binary>>) -> [{1, L,
Payload} | decode(Rest)];
decode(<<2, L:16/integer, Payload:L/binary, Rest/binary>>) -> [{2, L,
Payload} | decode(Rest)];
decode(<<3, L:24/integer, Payload:L/binary, Rest/binary>>) -> [{3, L,
Payload} | decode(Rest)];
decode(<<4, L:32/integer, Payload:L/binary, Rest/binary>>) -> [{4, L,
Payload} | decode(Rest)];
decode(<<>>) -> [].
It repeats, but it is pretty clear what is going on I think. If you are not
interested in the header type, you can possibly factor this out of the
recursive loop, which makes it even nicer to look at.

J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20200714/afb64e42/attachment.htm>


More information about the erlang-questions mailing list