[erlang-questions] Binary matching problem

Bengt Kleberg bengt.kleberg@REDACTED
Mon Feb 25 13:35:16 CET 2008


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




More information about the erlang-questions mailing list