Simplify the pkt parsing code

This commit is contained in:
Carlos Martín Nieto
2013-05-28 19:13:49 +02:00
parent 75e3d5416c
commit f410083711

View File

@@ -16,10 +16,8 @@ line(Text) ->
-spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. -spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}.
parse(In) -> parse(In) ->
case unpack(In) of case unpack(In) of
{error, ebufs} -> Err = {error, ebufs} ->
{error, ebufs}; Err;
{0, Rest} ->
{flush, Rest};
{Len, Rest} -> {Len, Rest} ->
parse_pkt(Rest, Len) parse_pkt(Rest, Len)
end. end.
@@ -27,43 +25,43 @@ parse(In) ->
-spec parse_request(iolist()) -> geef_request(). -spec parse_request(iolist()) -> geef_request().
parse_request(In) -> parse_request(In) ->
case unpack(In) of case unpack(In) of
{error, ebufs} -> Err = {error, ebufs} ->
{error, ebufs}; Err;
{_, Line} -> {_, Line} ->
%% Split it into request, host, rest (should be empty) %% Split it into request, host, rest (should be empty)
[S, H, _] = binary:split(Line, <<0>>, [global]), [S, H, _] = binary:split(Line, <<0:8>>, [global]),
case S of {Service, Path} = service_path(S),
<<"git-upload-pack ", Path/binary>> ->
Service = upload_pack;
<<"git-receive-pack ", Path/binary>> ->
Service = receive_pack
end,
<<"host=", Host/binary>> = H, <<"host=", Host/binary>> = H,
{ok, #geef_request{service=Service, path=Path, host=Host}} {ok, #geef_request{service=Service, path=Path, host=Host}}
end. end.
-spec unpack(iolist()) -> {error, ebufs} | {non_neg_integer(), binary()}. service_path(<<"git-upload-pack ", Path/binary>>) ->
unpack(In0) -> {upload_pack, Path};
In = iolist_to_binary(In0), service_path(<<"git-receive-pack ", Path/binary>>) ->
<<BLen:4/binary, Rest/binary>> = In, {receive_pack, Path}.
Len = binary_to_integer(BLen, 16),
if Len == 0 ->
{0, Rest};
Len - 4 > size(Rest) ->
{error, ebufs};
true ->
{Len - 4, Rest}
end.
parse_pkt(In, Len0) -> -spec unpack(iolist()) -> {error, ebufs} | {non_neg_integer(), binary()}.
io:format("~p, ~p~n", [In, Len0]), unpack(In) ->
Len1 = Len0 - 5, % "want " | "have " <<BLen:4/binary, Rest/binary>> = iolist_to_binary(In),
case In of Len = binary_to_integer(BLen, 16),
<<"want ", Sha:?SHA_LEN/binary, Rest0/binary>> -> do_unpack(Len, Rest).
Pkt = {want, geef_oid:parse(Sha)};
<<"have ", Sha:?SHA_LEN/binary, Rest0/binary>> -> do_unpack(0, Rest) ->
Pkt = {have, geef_oid:parse(Sha)} {0, Rest};
end, do_unpack(Len, Rest) when Len - 4 > size(Rest) ->
Len2 = Len1 - ?SHA_LEN, % get rid of the LF if we have it {error, ebufs};
<<_:Len2/binary, Rest/binary>> = Rest0, do_unpack(Len, Rest) ->
{Pkt, Rest}. {Len - 4, Rest}.
parse_pkt(In, 0) ->
{flush, In};
parse_pkt(In, Len) ->
LenLF = Len - 5 - ?SHA_LEN, % "want " | "want " + sha, remove LF if it's there
{Type, Rest0} = pkt_type(In),
<<Sha:?SHA_LEN/binary, _:LenLF/binary, Rest/binary>> = Rest0,
{{Type, geef_oid:parse(Sha)}, Rest}.
pkt_type(<<"have ", Rest/binary>>) ->
{have, Rest};
pkt_type(<<"want ", Rest/binary>>) ->
{want, Rest}.