root/widefinder/src/binbird.erl

Revision 91:b08cb886bf4e, 4.1 KB (checked in by dcaoyuan, 8 months ago)

Imported widefinder code.

Line 
1-module(binbird).
2
3
4-define(FILE_BUFFER_SIZE, 1024).
5%% The best Bin Buffer Size is 4096
6-define(BIN_BUFFER_SIZE, 4096).
7
8get_handle(FileName) ->
9    erlang:spawn_monitor(fun() -> start(FileName) end).
10
11get_lines({Pid, MRef}) ->
12    Pid ! {get_lines, MRef, self()},
13    receive
14        {{Data, Prep}, MRef} ->
15            case travel_bin_eval(Data) of
16                [H|T] ->
17                    [<<Prep/binary, H/binary>> | T];
18                [] ->
19                    [Prep]
20            end;
21        {eof, MRef} ->
22            eof;
23        {'DOWN', MRef, _Type, Pid, _Info} ->
24            erlang:fault(file_closed)
25    end.
26
27close({Pid, _}) ->
28    Pid ! stop.
29
30start(FileName) ->
31    {ok, F} = file:open(FileName, [raw, binary]),
32    serve_lines(F, <<>>).
33
34serve_lines(File,Rest) ->
35    {Data, Rest1} = get_more_data(File,Rest),
36    receive
37        {get_lines, Ref, Pid} ->
38            Pid ! {Data, Ref},
39            serve_lines(File, Rest1);
40        stop ->
41            file:close(File)
42    end.
43
44get_more_data(File, Rest) ->
45    case file:read(File, ?FILE_BUFFER_SIZE) of
46        eof when size(Rest) =:= 0 ->
47            {eof, <<>>};
48        eof ->
49            {{<<>>, Rest}, <<>>};
50        {ok, Bin} ->
51            case get_last_line(Bin) of
52                {Lines, Rest1} ->
53                    {{Lines, Rest}, Rest1};
54                Rest1 ->
55                    get_more_data(File, <<Rest/binary, Rest1/binary>>)
56            end
57    end.
58
59
60%% @doc split Bin on character C
61%% -spec(travel_bin_soft_hack/2::Bin::binary(), C:char() -> [binary]).
62get_until(Bin, Str) ->
63    StrSize = length(Str),
64    get_until_1(Bin, Str, StrSize, 0, []).
65
66get_until_1(Bin, Str, StrSize, Offset, Acc) ->
67    %% Compiler will build a decision tree for following binary pattern matchs
68    %% and optimaze it, so, knows how many bits will be traveled and tested.
69
70    case Bin of
71        <<_:Offset/binary,Str,_/binary>> ->
72            L = Offset,
73            <<New:L/binary, _, Rest/binary>> = Bin,
74            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
75        <<_:Offset/binary,_,Str,_/binary>> ->
76            L = Offset + StrSize,
77            <<New:L/binary, _, Rest/binary>> = Bin,
78            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
79        <<_:Offset/binary,_,_,Str,_/binary>> ->
80            L = Offset + 2 * StrSize,
81            <<New:L/binary, _, Rest/binary>> = Bin,
82            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
83        <<_:Offset/binary,_,_,_,Str,_/binary>> ->
84            L = Offset + 3 * StrSize,
85            <<New:L/binary, _, Rest/binary>> = Bin,
86            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
87        <<_:Offset/binary,_,_,_,_,Str,_/binary>> ->
88            L = Offset + 4 * StrSize,
89            <<New:L/binary, _, Rest/binary>> = Bin,
90            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
91        <<_:Offset/binary,_,_,_,_,_,Str,_/binary>> ->
92            L = Offset + 5 * StrSize,
93            <<New:L/binary, _, Rest/binary>> = Bin,
94            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
95        <<_:Offset/binary,_,_,_,_,_,_,Str,_/binary>> ->
96            L = Offset + 6 * StrSize,
97            <<New:L/binary, _, Rest/binary>> = Bin,
98            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
99        <<_:Offset/binary,_,_,_,_,_,_,_,Str,_/binary>> ->
100            L = Offset + 7 * StrSize,
101            <<New:L/binary, _, Rest/binary>> = Bin,
102            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
103        <<_:Offset/binary,_,_,_,_,_,_,_,_,Str,_/binary>> ->
104            L = Offset + 8 * StrSize,
105            <<New:L/binary, _, Rest/binary>> = Bin,
106            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
107        <<_:Offset/binary,_,_,_,_,_,_,_,_,_,Str,_/binary>> ->
108            L = Offset + 9 * StrSize,
109            <<New:L/binary, _, Rest/binary>> = Bin,
110            split_bin_soft_hack(Rest, Str, 0, [New | Acc]);
111        <<_:Offset/binary,_:80,_/binary>> ->
112            split_bin_soft_hack(Bin, Str, Offset + 10  * StrSize, Acc);
113        <<_:Offset/binary,_,_/binary>> ->
114            split_bin_soft_hack(Bin, Str, Offset + 1 * StrSize, Acc);
115        _ ->
116            {Bin, lists:reverse(Acc)}
117    end.
Note: See TracBrowser for help on using the browser.