From 59e40ca90dc1a26e1e728bcaec29b061c8b07d87 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Mon, 18 Jul 2016 01:19:08 +0200 Subject: Compact/Verbose --- bencode/bdecode.go | 22 ++++++++++++---------- tracker/messages.go | 26 ++++++++++++++++++++++---- tracker/messages_test.go | 5 ++--- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/bencode/bdecode.go b/bencode/bdecode.go index 837dbec..bda3dd7 100644 --- a/bencode/bdecode.go +++ b/bencode/bdecode.go @@ -9,7 +9,7 @@ import ( ) type Unmarshaler interface { - UnmarshalBencode([]byte) error + UnmarshalBencode([]byte) (int, error) } var ErrValue = errors.New("Unexpected value") @@ -19,14 +19,14 @@ type decodeState struct { off int } -func Unmarshal(data []byte, v interface{}) error { +func Unmarshal(data []byte, v interface{}) (int, error) { val := reflect.ValueOf(v) if val.Kind() != reflect.Ptr { - return errors.New("non-pointer passed to Unmarshal") + return 0, errors.New("non-pointer passed to Unmarshal") } d := decodeState{data: data} err := d.unmarshalField(val.Elem()) - return err + return d.off, err } func (d *decodeState) unmarshalField(v reflect.Value) error { @@ -57,14 +57,16 @@ func (d *decodeState) unmarshalDict(v reflect.Value) error { key, n := parseString(d.data[d.off:]) d.off += n val := findKey(key, v) - /* - if val.CanAddr() && val.Addr().Type().NumMethod() > 0 { - if u, ok := val.Addr().Interface().(Unmarshaler); ok { - u.UnmarshalBencode(d.data[d.off:]) - log.Println("has unmarshaler", u) + if val.CanAddr() && val.Addr().Type().NumMethod() > 0 { + if u, ok := val.Addr().Interface().(Unmarshaler); ok { + n, err := u.UnmarshalBencode(d.data[d.off:]) + if err != nil { + return err } + d.off += n + continue } - */ + } d.unmarshalField(val) } diff --git a/tracker/messages.go b/tracker/messages.go index 26d03c4..b32dd8a 100644 --- a/tracker/messages.go +++ b/tracker/messages.go @@ -65,9 +65,27 @@ func (p Peer) String() string { type Peers []Peer -func (p *Peers) UnmarshalBencode(b []byte) error { - log.Println(string(b)) - return nil +func (p *Peers) UnmarshalBencode(b []byte) (int, error) { + if b[0] == 'l' { + log.Println("verbose") + var tmp []Peer + n, err := bencode.Unmarshal(b, &tmp) + *p = Peers(tmp) + return n, err + } + log.Println("compact") + var tmp []byte + n, err := bencode.Unmarshal(b, &tmp) + addr, err := peerAddr(tmp) + *p = make(Peers, len(addr)) + for i, v := range addr { + peer := Peer{ + IP: v.IP.String(), + Port: int(v.Port), + } + (*p)[i] = peer + } + return n, err } func (r Request) Get(announce string) (Response, error) { @@ -90,7 +108,7 @@ func (r Request) Get(announce string) (Response, error) { } var res Response - err = bencode.Unmarshal(body, &res) + _, err = bencode.Unmarshal(body, &res) if err != nil { return fail(err) } diff --git a/tracker/messages_test.go b/tracker/messages_test.go index 8e33ea6..3cec8ee 100644 --- a/tracker/messages_test.go +++ b/tracker/messages_test.go @@ -46,13 +46,12 @@ func TestParsePeers(t *testing.T) { } func TestParseResponseCompact(t *testing.T) { - t.Skip() body, err := ioutil.ReadFile("../examples/tr_resp.compact") if err != nil { t.Error(err) } var resp Response - err = bencode.Unmarshal(body, &resp) + _, err = bencode.Unmarshal(body, &resp) if err != nil { t.Error(err) } @@ -65,7 +64,7 @@ func TestParseResponseVerbose(t *testing.T) { t.Error(err) } var resp Response - err = bencode.Unmarshal(body, &resp) + _, err = bencode.Unmarshal(body, &resp) if err != nil { t.Error(err) } -- cgit v1.2.3