From f410083711ef8abda82d0d5511e919dc03ff8dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 28 May 2013 19:13:49 +0200 Subject: [PATCH] Simplify the pkt parsing code --- src/geef_pkt.erl | 72 +++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) diff --git a/src/geef_pkt.erl b/src/geef_pkt.erl index 79350fa..55ad15f 100644 --- a/src/geef_pkt.erl +++ b/src/geef_pkt.erl @@ -16,10 +16,8 @@ line(Text) -> -spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. parse(In) -> case unpack(In) of - {error, ebufs} -> - {error, ebufs}; - {0, Rest} -> - {flush, Rest}; + Err = {error, ebufs} -> + Err; {Len, Rest} -> parse_pkt(Rest, Len) end. @@ -27,43 +25,43 @@ parse(In) -> -spec parse_request(iolist()) -> geef_request(). parse_request(In) -> case unpack(In) of - {error, ebufs} -> - {error, ebufs}; + Err = {error, ebufs} -> + Err; {_, Line} -> %% Split it into request, host, rest (should be empty) - [S, H, _] = binary:split(Line, <<0>>, [global]), - case S of - <<"git-upload-pack ", Path/binary>> -> - Service = upload_pack; - <<"git-receive-pack ", Path/binary>> -> - Service = receive_pack - end, + [S, H, _] = binary:split(Line, <<0:8>>, [global]), + {Service, Path} = service_path(S), <<"host=", Host/binary>> = H, {ok, #geef_request{service=Service, path=Path, host=Host}} end. --spec unpack(iolist()) -> {error, ebufs} | {non_neg_integer(), binary()}. -unpack(In0) -> - In = iolist_to_binary(In0), - <> = In, - Len = binary_to_integer(BLen, 16), - if Len == 0 -> - {0, Rest}; - Len - 4 > size(Rest) -> - {error, ebufs}; - true -> - {Len - 4, Rest} - end. +service_path(<<"git-upload-pack ", Path/binary>>) -> + {upload_pack, Path}; +service_path(<<"git-receive-pack ", Path/binary>>) -> + {receive_pack, Path}. -parse_pkt(In, Len0) -> - io:format("~p, ~p~n", [In, Len0]), - Len1 = Len0 - 5, % "want " | "have " - case In of - <<"want ", Sha:?SHA_LEN/binary, Rest0/binary>> -> - Pkt = {want, geef_oid:parse(Sha)}; - <<"have ", Sha:?SHA_LEN/binary, Rest0/binary>> -> - Pkt = {have, geef_oid:parse(Sha)} - end, - Len2 = Len1 - ?SHA_LEN, % get rid of the LF if we have it - <<_:Len2/binary, Rest/binary>> = Rest0, - {Pkt, Rest}. +-spec unpack(iolist()) -> {error, ebufs} | {non_neg_integer(), binary()}. +unpack(In) -> + <> = iolist_to_binary(In), + Len = binary_to_integer(BLen, 16), + do_unpack(Len, Rest). + +do_unpack(0, Rest) -> + {0, Rest}; +do_unpack(Len, Rest) when Len - 4 > size(Rest) -> + {error, ebufs}; +do_unpack(Len, 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), + <> = Rest0, + {{Type, geef_oid:parse(Sha)}, Rest}. + +pkt_type(<<"have ", Rest/binary>>) -> + {have, Rest}; +pkt_type(<<"want ", Rest/binary>>) -> + {want, Rest}.