[erlang-questions] segments of variable length

Steve Davis <>
Sat Apr 4 00:46:33 CEST 2009


You were originally on the right track, but look back to the original
implementation you had and ask yourself this question:

--- When does the UnitID field _end_ and Time field _begin_?

If you, as a human being looking at the binary, cannot be sure, then
you cannot expect your program to determine that, hence...

...the two variable binary fields are "indeterminate"

You need to find a way to flag where one ends and the next begins in
the binary encoding.

:)


On Apr 3, 11:13 am, "Gamoto" <> wrote:
> -module(aa).
> -define(X,<<131,107,0,18,36,65,86,82,77,67,44,49,50,51,52,44,49,53,49,55,51 ,54>>).
> -export([start/0]).
>
> start()->
>    case binary_to_term(?X) of
>             {<<H,U,T>>}->
>              io:format("Header = ~s~n",[H]),
>              io:format("Unit ID = ~s~n",[U]),
>              io:format("Time = ~s~n",[T])
>         end.
>
> This gives me an error.
> I was waiting for
> Header = $AVRMC
> Unit ID = 1234
> Time =  151736
>
> The most important for me is to obtain H,U and T
>
>
>
>
>
>
>
> >> I receive from several machines messages and I would like to extract data.
> >> My first approach was:
>
> >> handler(Data)->
> >>     case Data of
> >>         <>
> >>         etc...
>
> >> My problem is that some segment have a fixed length (header, Status) and some
> >> others a variable length (Time <= 6 bytes, UnitID <= 8 bytes).
> >> My approach is bad. I thought to do:      Segments = string:tokens(Data,",")
> >> This separates the segments but I don't have their name
> >> (header,unitid,time,status) !
> >> Could you advice me a better approach. My goal is to check each segment and make
> >> actions according to their values.
>
> >You need to define a message format such that the required information is present to determine how to parse the rest of the message. This isn't really an erlang-specific problem but erlang is very good at supporting this.
>
> >As an example you could use erlang:term_to_binary() and binary_to_term() for the message encoding on the wire. binary_to_term() might fail if the message is incomplete. This is where the {packet, N} inet options for connect/listen come in, eg. {packet,2} will only return complete messages; the length header is added automatically on send and stripped on receive so you only need to do, eg.
>
> >gen_tcp:send( Sock, term_to_binary( MessageTerm ) )
>
> >and if you receive {tcp, Sock, Data}, then it is safe to call
>
> >MessageTerm = binary_to_term(Data)
>
> >Check out the inet module documentation. There are lots of useful options.
>
> >Hope that is useful
>
> >--
> >  Rich
>
> >      The new Internet Explorer 8 optimised for Yahoo!7: Faster, Safer, Easier.
>
> _______________________________________________
> erlang-questions mailing list
> ://www.erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list