From 03f43d3265e0bc2628be2ad2e9bc1a14f64bc0e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Mon, 27 May 2013 10:56:19 +0200 Subject: [PATCH] pkt: parse want and have lines --- src/geef_pkt.erl | 32 +++++++++++++++++++++++++++++++- test/pkt_test.erl | 12 ++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 test/pkt_test.erl diff --git a/src/geef_pkt.erl b/src/geef_pkt.erl index 025df6a..c01b038 100644 --- a/src/geef_pkt.erl +++ b/src/geef_pkt.erl @@ -1,6 +1,10 @@ -module(geef_pkt). --export([line/1]). +-export([line/1, parse/1]). + +-include("geef_records.hrl"). + +-define(SHA_LEN, 40). -spec line(iolist()) -> iolist(). line(Text) -> @@ -8,3 +12,29 @@ line(Text) -> Len = 4 + iolist_size(Text) + 1, Prefix = io_lib:format("~4.16.0b", [Len]), [Prefix, Text, "\n"]. + +-spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. +parse(In0) -> + In = iolist_to_binary(In0), + <> = In, + Len = binary_to_integer(BLen, 16), + case Len of + 0 -> + flush; + _ -> + parse_pkt(Rest, Len - 4) + end. + +parse_pkt(In, Len) when size(In) < Len -> + {error, ebufs}; +parse_pkt(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}. diff --git a/test/pkt_test.erl b/test/pkt_test.erl new file mode 100644 index 0000000..5c3c9e2 --- /dev/null +++ b/test/pkt_test.erl @@ -0,0 +1,12 @@ +-module(pkt_test). +-compile([export_all]). +-include_lib("eunit/include/eunit.hrl"). +-include("src/geef_records.hrl"). + +flush_test() -> + geef_pkt:parse("0000"). + +have_test() -> + Expected = {{want, geef_oid:parse("e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463")}, <<>>}, + Actual = geef_pkt:parse("0032want e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463\n"), + ?assertEqual(Expected, Actual).