Current section
Files
Jump to
Current section
Files
src/bread_server.erl
%% -*- mode: erlang; erlang-indent-level: 2 -*-
%%% Created : 10 Jun 2009 by Mats Cronqvist <masse@kreditor.se>
%% @doc
%% @end
-module('bread_server').
-author('Mats Cronqvist').
-export([get_bread/0
, stop/0
, start/1
, start/2]).
-export([rec_info/1
, init/1
, handle_info/2]).
%% the api
start(FilePattern) ->
start(FilePattern,guess).
start(FilePattern,Type) ->
case filelib:wildcard(FilePattern) of
[File|Files] -> gen_serv:start(?MODULE,{File,Files,Type});
[] -> exit({no_files,FilePattern})
end.
stop() ->
gen_serv:stop(?MODULE).
get_bread() ->
Ref = erlang:monitor(process,?MODULE),
try
?MODULE ! {get_bread,self()},
receive
{bread,Bread} -> Bread;
{'DOWN',Ref,process,_,_} -> eof
end
catch
error:badarg -> eof
after
erlang:demonitor(Ref,[flush])
end.
%% state
-record(ld,{file,files,type,bread_pid,bread_ref}).
rec_info(ld) -> record_info(fields,ld).
%% gen_serv callbacks
init({File,Files,Type}) ->
gen_serv:unlink(),
start_breader(File,Files,#ld{type=Type}).
handle_info({'DOWN',BR,_,BP,normal},LD = #ld{bread_pid=BP,bread_ref=BR}) ->
case LD#ld.files of
[File|Files] -> start_breader(File,Files,LD);
[] -> {stop,normal,LD}
end;
handle_info({'DOWN',BR,_,BP,R},LD = #ld{bread_pid=BP,bread_ref=BR}) ->
erlang:display(R),
{stop,normal,LD};
handle_info({get_bread,Pid},LD) ->
LD#ld.bread_pid ! {get_bread,Pid},
LD.
%% implementation
start_breader(File,Files,LD) ->
{BP,BR} = spawn_monitor(fun() -> breader(File,LD#ld.type) end),
LD#ld{file=File,files=Files,bread_pid=BP,bread_ref=BR}.
%% runs in its own process
breader(File,guess) ->
breader(File,guess_type(filename:extension(File)));
breader(File,Type) ->
bread:fold(File,fun breaded/2,0,[Type]).
breaded(Blob,N) ->
receive
quit -> exit(N);
{get_bread,Pid} -> Pid ! {bread,Blob}, N+1
end.
guess_type(".txt") -> line;
guess_type(".xml") -> xml;
guess_type(".trc") -> trc.