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

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
	netmsg "github.com/jbenet/go-ipfs/net/message"
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
	nm "github.com/jbenet/go-ipfs/net/message"
	peer "github.com/jbenet/go-ipfs/peer"
	u "github.com/jbenet/go-ipfs/util"
)

type BitSwapMessage interface {
	Wantlist() []u.Key
	Blocks() []blocks.Block
	AppendWanted(k u.Key)
	AppendBlock(b blocks.Block)
	Exportable
}

type Exportable interface {
	ToProto() *PBMessage
	ToNet(p *peer.Peer) (nm.NetMessage, error)
}

// message wraps a proto message for convenience
type message struct {
27 28
	wantlist []u.Key
	blocks   []blocks.Block
29 30 31 32 33 34
}

func New() *message {
	return new(message)
}

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
func newMessageFromProto(pbm PBMessage) (BitSwapMessage, error) {
	m := New()
	for _, s := range pbm.GetWantlist() {
		m.AppendWanted(u.Key(s))
	}
	for _, d := range pbm.GetBlocks() {
		b, err := blocks.NewBlock(d)
		if err != nil {
			return nil, err
		}
		m.AppendBlock(*b)
	}
	return m, nil
}

50 51
// TODO(brian): convert these into keys
func (m *message) Wantlist() []u.Key {
52
	return m.wantlist
53 54 55 56
}

// TODO(brian): convert these into blocks
func (m *message) Blocks() []blocks.Block {
57
	return m.blocks
58 59 60
}

func (m *message) AppendWanted(k u.Key) {
61
	m.wantlist = append(m.wantlist, k)
62 63 64
}

func (m *message) AppendBlock(b blocks.Block) {
65
	m.blocks = append(m.blocks, b)
66 67 68
}

func FromNet(nmsg netmsg.NetMessage) (BitSwapMessage, error) {
69 70 71 72 73 74 75 76 77
	pb := new(PBMessage)
	if err := proto.Unmarshal(nmsg.Data(), pb); err != nil {
		return nil, err
	}
	m, err := newMessageFromProto(*pb)
	if err != nil {
		return nil, err
	}
	return m, nil
78 79 80
}

func (m *message) ToProto() *PBMessage {
81 82 83 84 85 86 87 88
	pb := new(PBMessage)
	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
89 90 91 92 93
}

func (m *message) ToNet(p *peer.Peer) (nm.NetMessage, error) {
	return nm.FromObject(p, m.ToProto())
}