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

Oliver Korpilla Oliver.Korpilla@REDACTED
Tue Jul 14 22:57:10 CEST 2020


Hi,

I'm not sure the example data was correct. I see Leornard also changed that one:

start() ->
    Data = << 1,2,"a","b", 3,0,0,1,"x", 4,0,0,0,1,"y", 4,0,0,0,2,"m", "n" >>,
    io:format("~p~n", [ extract(Data) ]).

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) ].
 
Regards,
Oliver

Gesendet: Dienstag, 14. Juli 2020 um 22:24 Uhr
Von: "Leonard B" <leonard.boyce@REDACTED>
An: "Papa Tana" <papa.tana101@REDACTED>
Cc: "erlang-questions" <erlang-questions@REDACTED>
Betreff: Re: Decode a trail of <<Header,Length,Payload,......,Header,Length, Payload,.......>> from Binary Input
rough and there's probably a better way but should work:

%% Data = <<1,2:(1*8),"a","b",2,3:(2*8),"a","b","c",3,1:(3*8),"x",4,1:(4*8),"y",8,2:(8*8),"m","n">>.

d(Data) ->
d(Data, []).

d(<<X:8, Rest0/binary>>, Acc) ->
Len = X * 8,
<<LenVal:Len, Rest/binary>> = Rest0,
<<D:LenVal/binary, Tl/binary>> = Rest,
io:format("Len: ~p LenVal: ~p D: ~p~n", [Len, LenVal, D]),
io:format("Tl: ~p~n", [Tl]),
d(Tl, [{X, D} | Acc]);
d(<<>>, Acc) ->
lists:reverse(Acc).

56> bt:d(Data).
Len: 8 LenVal: 2 D: <<"ab">>
Tl: <<2,0,3,97,98,99,3,0,0,1,120,4,0,0,0,1,121,8,0,0,0,0,0,0,0,2,109,110>>
Len: 16 LenVal: 3 D: <<"abc">>
Tl: <<3,0,0,1,120,4,0,0,0,1,121,8,0,0,0,0,0,0,0,2,109,110>>
Len: 24 LenVal: 1 D: <<"x">>
Tl: <<4,0,0,0,1,121,8,0,0,0,0,0,0,0,2,109,110>>
Len: 32 LenVal: 1 D: <<"y">>
Tl: <<8,0,0,0,0,0,0,0,2,109,110>>
Len: 64 LenVal: 2 D: <<"mn">>
Tl: <<>>
[{1,<<"ab">>},
{2,<<"abc">>},
{3,<<"x">>},
{4,<<"y">>},
{8,<<"mn">>}]



Leonard

On Tue, Jul 14, 2020 at 3:48 PM Papa Tana <papa.tana101@REDACTED> wrote:
>
> Dear All,
>
> I am working with some Binary Input as below, which complete format is:
>
> Data =
> <<
>
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(8bits) | Payload |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(16bits) | Payload|
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(32bits) | Payload|
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(8bits) | Payload |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(32bits) | Payload|
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(16bits) | Payload|
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(8bits) | Payload |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> |Header | LENGTH(16bits) | Payload|
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>
> >>
>
> - Header is always 8 bits,
> - LENGTH has a dynamic size(can be 8 "if Header=1", 16 "if Header=2",
> 24 "if Header=3" or 32 "if Header=4")
> - Payload is deducted from LENGTH
>
> I am doing something like this in my Code(repetitive check), because I
> have to test Data for every possible value of Header (impossible to
> maintain such a code):
>
> [ {Header, LENGTH, Payload} || <<Header:8, LENGTH:8 if Header = 1,
> Payload:LENGTH*8>> <= Data ]
> [ {Header, LENGTH, Payload} || <<Header:8, LENGTH:16 if Header = 2,
> Payload:LENGTH*8>> <= Data ]
> [ {Header, LENGTH, Payload} || <<Header:8, LENGTH:24 if Header = 3,
> Payload:LENGTH*8>> <= Data ]
> [ {Header, LENGTH, Payload} || <<Header:8, LENGTH:32 if Header = 4,
> Payload:LENGTH*8>> <= Data ]
>
> Is there any way to extract all {Header, LENGTH, Payload} in this Data
> Binary Input in a more efficient way please?
>
> An example of Data:
>
> Data =
> <<
> 1,2,"a","b",
> 3,1,"x",
> 4,1,"y",
> 8,2,"m", "n"
> >>.
>
> Thanks in advance,
>
> Best Regards,


More information about the erlang-questions mailing list