message.go 2.21 KB
Newer Older
1
package message
2 3

import (
4
	proto "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
5
	blocks "github.com/jbenet/go-ipfs/blocks"
6
	pb "github.com/jbenet/go-ipfs/exchange/bitswap/message/internal/pb"
7
	netmsg "github.com/jbenet/go-ipfs/net/message"
8
	nm "github.com/jbenet/go-ipfs/net/message"
9 10 11 12
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
)

13 14 15
// TODO move message.go into the bitswap package
// TODO move bs/msg/internal/pb to bs/internal/pb and rename pb package to bitswap_pb

16
type BitSwapMessage interface {
17
	Wantlist() []u.Key
18
	Blocks() []blocks.Block
19
	AddWanted(k u.Key)
20
	AddBlock(b blocks.Block)
21 22 23 24
	Exportable
}

type Exportable interface {
25
	ToProto() *pb.Message
26
	ToNet(p peer.Peer) (nm.NetMessage, error)
27 28
}

29
type impl struct {
30
	wantlist map[u.Key]struct{}
31
	blocks   map[u.Key]blocks.Block
32 33
}

34
func New() BitSwapMessage {
35
	return &impl{
36
		wantlist: make(map[u.Key]struct{}),
37
		blocks:   make(map[u.Key]blocks.Block),
38
	}
39 40
}

41
func newMessageFromProto(pbm pb.Message) BitSwapMessage {
42 43
	m := New()
	for _, s := range pbm.GetWantlist() {
44
		m.AddWanted(u.Key(s))
45 46
	}
	for _, d := range pbm.GetBlocks() {
47
		b := blocks.NewBlock(d)
48
		m.AddBlock(*b)
49
	}
50
	return m
51 52
}

53
// TODO(brian): convert these into keys
54
func (m *impl) Wantlist() []u.Key {
55 56 57 58 59
	wl := make([]u.Key, 0)
	for k, _ := range m.wantlist {
		wl = append(wl, k)
	}
	return wl
60 61 62
}

// TODO(brian): convert these into blocks
63
func (m *impl) Blocks() []blocks.Block {
64 65 66 67 68
	bs := make([]blocks.Block, 0)
	for _, block := range m.blocks {
		bs = append(bs, block)
	}
	return bs
69 70
}

71
func (m *impl) AddWanted(k u.Key) {
72
	m.wantlist[k] = struct{}{}
73 74
}

75
func (m *impl) AddBlock(b blocks.Block) {
76
	m.blocks[b.Key()] = b
77 78
}

79
func FromNet(nmsg netmsg.NetMessage) (BitSwapMessage, error) {
80
	pb := new(pb.Message)
81 82 83
	if err := proto.Unmarshal(nmsg.Data(), pb); err != nil {
		return nil, err
	}
84
	m := newMessageFromProto(*pb)
85
	return m, nil
86 87
}

88
func (m *impl) ToProto() *pb.Message {
89
	pb := new(pb.Message)
90 91 92 93 94 95 96
	for _, k := range m.Wantlist() {
		pb.Wantlist = append(pb.Wantlist, string(k))
	}
	for _, b := range m.Blocks() {
		pb.Blocks = append(pb.Blocks, b.Data)
	}
	return pb
97 98
}

99
func (m *impl) ToNet(p peer.Peer) (nm.NetMessage, error) {
100 101
	return nm.FromObject(p, m.ToProto())
}