aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2016-07-18 01:19:08 +0200
committerDimitri Sokolyuk <demon@dim13.org>2016-07-18 01:19:08 +0200
commit59e40ca90dc1a26e1e728bcaec29b061c8b07d87 (patch)
tree2271c72710e08cd3232e6e86d68460bce4e6cde3
parente4b008b534de791b10864cbb4cab34fcee471c34 (diff)
Compact/Verbose
-rw-r--r--bencode/bdecode.go22
-rw-r--r--tracker/messages.go26
-rw-r--r--tracker/messages_test.go5
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)
}