[erlang-questions] Binary matching problem

Per Gustafsson per.gustafsson@REDACTED
Mon Feb 25 16:50:25 CET 2008


This is really a bug R12-B. The following shorter function gives a 
function clause error when called with <<0,0,0,0,0,1,0>> even though it 
should handle all 7 byte binaries.

parse(<<A:1/binary,B:3/binary,
       _C:1/binary,
       0:8, D:8>>) ->
    {A,B,D};
parse(<<A:1/binary,B:3/binary,_C:3/binary>>) ->
    {A,B}.

It seems that there is a bug somewhere in the pattern matching compiler. 
  A necessary condition for this bug seems to be that the size of the B 
matching is the same as the size of the _C matching.

Per


Tomas Stejskal wrote:
> It doesn't really work for me. I have erlang R12B-1 and it seems you've 
> tried it out on version R11B5, maybe it's a bug in R12.
> 
> /Tom
> 
> Bengt Kleberg wrote:
>> Greetings,
>>
>> The example file and code works for me.
>>
>> Erlang (BEAM) emulator version 5.5.5.5
>> 2> id3_v1:read_v1_or_v11_tag("id3_v1.mp3").
>> {ok,{"ID3v1",
>>      [{title,<<68,117,154,105,232,107,121>>},
>>       {artist,<<"Daniel Landa">>},
>>       {album,<<"Best Of">>}]}}
>>
>>
>> bengt
>>
>> On Sat, 2008-02-23 at 14:58 +0100, Tomas Stejskal wrote:
>>> Hello,
>>>
>>> as a newbie I've played with the module id3_v1.erl from Joe's book and 
>>> I've found some strange behavior regarding binary matching. The module's 
>>> purpose is reading an id3 version 1 or version 1.1 tag from a mp3 file.
>>>
>>> Here is modified version of the module:
>>>
>>> ---
>>> -module(id3_v1).
>>> -export([read_v1_or_v11_tag/1, read_only_v1_tag/1]).
>>> -import(lists, [reverse/1]).
>>>
>>> read_v1_or_v11_tag(File) ->
>>>     read_id3_tag(File, fun parse_v1_or_v11_tag/1).
>>>
>>> read_only_v1_tag(File) ->
>>>     read_id3_tag(File, fun parse_only_v1_tag/1).
>>>
>>> read_id3_tag(File, Parse) ->
>>>     case file:open(File, [read, binary, raw]) of
>>>     {ok, S} ->
>>>         Size = filelib:file_size(File),
>>>         {ok, Bin} = file:pread(S, Size - 128, 128),
>>>         Result = Parse(Bin),
>>>         file:close(S),
>>>         Result;
>>>     Error ->
>>>         {File, Error}
>>>     end.
>>>
>>> parse_only_v1_tag(<<"TAG", Title:30/binary,
>>>            Artist:30/binary, Album:30/binary,
>>>            _Year:4/binary, _Comment:30/binary,
>>>            _Genre:8>>) ->
>>>     {ok,
>>>      {"ID3v1",
>>>       [{title, trim(Title)},
>>>        {artist, trim(Artist)},
>>>        {album, trim(Album)}]}};
>>> parse_only_v1_tag(_) ->
>>>     error.
>>>
>>> parse_v1_or_v11_tag(<<"TAG", Title:30/binary,
>>>        Artist:30/binary, Album:30/binary,
>>>        _Year:4/binary, _Comment:28/binary,
>>>        0:8, Track:8, _Genre:8>>) ->
>>>     {ok,
>>>      {"ID3v1.1",
>>>       [{track, Track}, {title, trim(Title)},
>>>        {artist, trim(Artist)}, {album, trim(Album)}]}};
>>> parse_v1_or_v11_tag(<<"TAG", Title:30/binary,
>>>           Artist:30/binary, Album:30/binary,
>>>           _Year:4/binary, _Comment:30/binary,
>>>           _Genre:8>>) ->
>>>     {ok,
>>>      {"ID3v1",
>>>       [{title, trim(Title)},
>>>        {artist, trim(Artist)},
>>>        {album, trim(Album)}]}};
>>> parse_v1_or_v11_tag(_) ->
>>>     error.
>>>    
>>> trim(Bin) ->
>>>     list_to_binary(trim_blanks(binary_to_list(Bin))).
>>>
>>> trim_blanks(L) ->
>>>     reverse(skip_blanks_and_zero(reverse(L))).
>>>
>>> skip_blanks_and_zero([$\s|T]) ->
>>>     skip_blanks_and_zero(T);
>>> skip_blanks_and_zero([0|T]) ->
>>>     skip_blanks_and_zero(T);
>>> skip_blanks_and_zero(L) ->
>>>     L.
>>> ---
>>>
>>> When I use the function read_v1_or_v11_tag on a mp3 file containing 
>>> version 1 tag, it returns an error. However, when the function 
>>> read_only_v1_tag is applied on the same file, it reads the tag data 
>>> correctly. The only difference between these two functions is that the 
>>> former has an extra branch to read version 1.1 tag.
>>>
>>> Is this a bug or have I missed something?
>>>
>>> I've included an example file which contains only the id3 v1 tag data 
>>> (last 128 bytes of the mp3 file).
>>>
>>> Thanks in advance
>>>
>>> /Tom
>>>
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://www.erlang.org/mailman/listinfo/erlang-questions
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://www.erlang.org/mailman/listinfo/erlang-questions
> 
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions




More information about the erlang-questions mailing list