Practical Binary Pattern Matching

Eric Newhuis <>
Wed Dec 4 15:16:10 CET 2002


I am attempting to parse a byte stream with variable-length records that
consist of attribute-value pairs and my code looks like this:

parseElements (Body) ->
  case Body of
    <<Attribute:2/big-unsigned-integer-unit:8, ?ELEM_LONG_LENGTH,
Length:4/big-unsigned-integer-unit:8, Rest/binary>> ->
      case Rest of
        <<Raw:Length/binary>> ->
          out (Attribute, valueOf (Attribute, Raw));
        <<Raw:Length/binary, Rest/binary>> ->
          out (Attribute, valueOf (Attribute, Raw)),
          parseElements (Rest)
      end;
    <<Attribute:2/big-unsigned-integer-unit:8, Length, Rest/binary>> ->
      case Rest of
        <<Raw:Length/binary>> ->
          out (Attribute, valueOf (Attribute, Raw));
        <<Raw:Length/binary, Rest/binary>> ->
          out (Attribute, valueOf (Attribute, Raw)),
          parseElements (Rest)
      end
  end.

I've have nested binary pattern matching and I suspect that leads to
inefficiencies due to the fact that I must pattern-match more than once
for each record.  Is there an easier way to do this?  Like this?

    <<Attribute:2/big-unsigned-integer-unit:8, Length,
Raw:Length/binary, Rest/binary>> -> ...

Where Rest can match <<>> and Length can be used with Raw:Length before
it is bound?

Or maybe there is some other simplification I have overlooked.

Or maybe this is fast enough for my application?  I don't know yet.

Sincerely,
Eric Newhuis




More information about the erlang-questions mailing list