Bertaud
Bertaud

Reputation: 2918

splitting of binaries

I tried to split two fields from a binary string:

-define(S,<<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,‌​0110,00,150,0,0,0\0">>).<<Message_length:4/binary,Msg/binary>> = S.

the first 4 bytes are the length of the following message, the other byte are the message,
a null byte terminates the string.

The result is: ** exception error: o match of right hand side value
EDIT Just before the given code, there is:

[Sequence|Reste] = binary:split(T,<<"\0">>),

Does "Reste" bounded ?

Upvotes: 2

Views: 1235

Answers (3)

Hynek -Pichi- Vychodil
Hynek -Pichi- Vychodil

Reputation: 26121

There is issue with erlang string escape interpolation. The fourth byte is not interpolated as "\0" but "\052".

1> Bin = <<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0\0">>.
<<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,                                                                                                                     
  48,48,48,48,48,48,48,56,44,48,...>>

So you have to write it in this manner.

2> f().
ok
3> Bin = <<"M\0\0\0","522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0\0">>.
<<77,0,0,0,53,50,50,48,51,57,51,53,53,48,57,57,44,48,49,
  48,49,48,48,48,48,48,48,48,56,...>>

Then usual way to parse this form of messages is:

4> <<L:32/little,Rest/binary>> = Bin.
<<77,0,0,0,53,50,50,48,51,57,51,53,53,48,57,57,44,48,49,
  48,49,48,48,48,48,48,48,48,56,...>>
5> L.
77
6> <<Msg:L/binary,R/binary>> = Rest.
<<"522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0"...>>
7> R.
<<0>>
8> Msg.
<<"522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,0110,00,150,0,0,0">>

Upvotes: 1

marcelog
marcelog

Reputation: 7180

Your code is ok, so either you dont have a binary string, or the length of Mystring does not comply with the pattern. Here's a quick test:

1> Mystring = <<"abcde">>.
<<"abcde">>
2> <<Message_length:4/binary,Msg/binary>> = Mystring.
<<"abcde">>
3> Message_length.
<<"abcd">>
4> Msg.
<<"e">>

If you have a string (a list of integers) instead of a binary string (<<"string">>), as Vincenzo suggested, call erlang:list_to_binary/1 first.

Hope it helps

EDIT: I've checked the example string you left in a comment of Vincenzo's answer. I've tried it with your code and still works. Is it possible that Message_length and/or Msg are already bound (and different to Mystring) when reaching that line of code? That would make the pattern matching fail.

EDIT2: Tested with the updated data in the question:

1> S = <<"M\0\0\0522039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,\342\200\214\342\200\2130110,00,150,0,0,0\0">>.
<<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,
  48,48,48,48,48,48,48,56,44,48,...>>
2> <<Message_length:4/binary,Msg/binary>> = S.
<<77,0,0,42,50,48,51,57,51,53,53,48,57,57,44,48,49,48,49,
  48,48,48,48,48,48,48,56,44,48,...>>
3> Message_length.
<<77,0,0,42>>
4> Msg.
<<"2039355099,010100000008,0,010170000000,0,0,0,0,0,0,,,0,0,,\342"...>>

Upvotes: 4

Vincenzo Maggio
Vincenzo Maggio

Reputation: 3869

You have to call list_to_binary/1 on string to be matched.

If you have further problems, type example string please!

Upvotes: 0

Related Questions