aboutsummaryrefslogblamecommitdiffstats
path: root/lib/hipe/test/bs_SUITE_data/bs_id3.erl
blob: a6152f05cdb5295dd3a5fc6213853415241a4b77 (plain) (tree)










































































                                                                            
%% -*- erlang-indent-level: 2 -*-
%%==========================================================================
%% From: Tomas Stejskal -- 23/02/2008
%% 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 an mp3 bin.
%% When I use the function read_v1_or_v11_tag on a mp3 binary 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.
%% This was a BEAM compiler bug which was fixed by a patch to beam_dead.
%%==========================================================================

-module(bs_id3).

-export([test/0]).

-define(BIN, <<84,65,71,68,117,154,105,232,107,121,0,0,0,0,0,0,0,0,0,0,0,
	       0,0,0,0,0,0,0,0,0,0,0,0,68,97,110,105,101,108,32,76,97,110,
	       100,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,101,115,116,
	       32,79,102,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
	       50,48,48,48,50,48,48,48,32,45,32,66,101,115,116,32,79,102,
	       32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,12>>).

test() ->
  R1 = parse_only_v1_tag(?BIN),
  R2 = parse_v1_or_v11_tag(?BIN),
  %% io:format("~p\n~p\n", [R1, R2]),
  R1 = R2,	% crash if not equal
  ok.

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) ->
  lists:reverse(skip_blanks_and_zero(lists: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.