-module(oma). -export([parse_header/1]). %% %% API %% parse_header(File) -> case file:open(File, [read, binary, raw]) of {ok, S} -> {ok, Header} = file:pread(S, 0, 16#0c60), H = case read_header(Header) of error -> {error, invalid_header}; Data -> Data end, file:close(S), H; _ -> {error, file_cannot_be_opened} end. %% %% Internal functions %% read_header(<<$e, $a, $3, Rest/binary>>) -> Data = decode_header(Rest, []), Data; read_header(_) -> error. % Title decode_header(<<$T, $I, $T, $2, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> TitleLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{title, Title}]); % Artist decode_header(<<$T, $P, $E, $1, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> ArtistLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{artist, Artist}]); % Album decode_header(<<$T, $A, $L, $B, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> AlbumLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{album, Album}]); % Genre decode_header(<<$T, $C, $O, $N, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> GenreLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{genre, Genre}]); % Track number decode_header(<<$T, $X, $X, $X, _:8/binary, $O, 0, $M, 0, $G, 0, 95, 0, $T, 0, $R, 0, $A, 0, $C, 0, $K, 0, 0, 0, Track:1/binary, Rest/binary>>, L) -> decode_header(Rest, [L|{track, list_to_integer(binary_to_list(Track))}]); % Year decode_header(<<$T, $Y, $E, $R, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> YearLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{year, Year}]); % Length decode_header(<<$T, $L, $E, $N, _:2/binary, Var:2/integer-unit:8, _:4/binary, Rest/binary>>, L) -> LenLength = Var - 2, <> = Rest, decode_header(Rest2, [L|{length, Length}]); decode_header(<<$E, $A, $3, $0, 16#60, 16#FF, 16#FF, _Rest/binary>>, L) -> L; decode_header(<<>>, L) -> L; decode_header(Bin, L) -> {_, NewBin} = split_binary(Bin, 1), decode_header(NewBin, L).