2
0
mirror of synced 2025-02-24 14:48:27 +00:00

Add some basic protocol definitions, this will be improved in the future

This commit is contained in:
Matt Joiner 2013-09-26 13:43:46 +10:00
parent d7ed035ef1
commit 0866ce3579
2 changed files with 128 additions and 0 deletions

116
protocol/protocol.go Normal file
View File

@ -0,0 +1,116 @@
package protocol
import (
"bytes"
"encoding/binary"
"errors"
// "errors"
"fmt"
"io"
"io/ioutil"
// "os"
)
type (
MessageType byte
Integer uint32
PieceIndex Integer
PieceOffset Integer
)
const (
Choke MessageType = iota
Unchoke
Interested
NotInterested
Have
Bitfield
Request
Piece
Cancel
)
type Message struct {
KeepAlive bool
Type MessageType
Bitfield []bool
Index PieceIndex
Begin PieceOffset
Length Integer
Piece []byte
}
func (msg *Message) UnmarshalReader(r io.Reader) (err error) {
err = binary.Read(r, binary.BigEndian, &msg.Type)
switch err {
case nil:
msg.KeepAlive = false
case io.EOF:
msg.KeepAlive = true
err = nil
return
default:
return
}
switch msg.Type {
case Choke, Unchoke, Interested, NotInterested:
case Have:
err = binary.Read(r, binary.BigEndian, &msg.Index)
case Request, Cancel:
err = binary.Read(r, binary.BigEndian, &msg.Index)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &msg.Begin)
if err != nil {
return
}
err = binary.Read(r, binary.BigEndian, &msg.Length)
case Bitfield:
// var bf []byte
_, err = ioutil.ReadAll(r)
if err != nil {
return
}
case Piece:
default:
return fmt.Errorf("unknown type: %v", msg.Type)
}
return
}
func (msg *Message) MarshalBinary() (b []byte, err error) {
w := &bytes.Buffer{}
if msg.KeepAlive {
b = w.Bytes()
return
}
err = w.WriteByte(byte(msg.Type))
if err != nil {
return
}
switch msg.Type {
case Choke, Unchoke, Interested, NotInterested:
case Have:
err = binary.Write(w, binary.BigEndian, msg.Index)
case Request, Cancel:
err = binary.Write(w, binary.BigEndian, msg.Index)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, msg.Begin)
if err != nil {
return
}
err = binary.Write(w, binary.BigEndian, msg.Length)
case Bitfield, Piece:
panic("unimplemented")
default:
err = errors.New("unknown type")
return
}
if err == nil {
b = w.Bytes()
}
return
}

12
protocol/protocol_test.go Normal file
View File

@ -0,0 +1,12 @@
package protocol
import (
"testing"
)
func TestConstants(t *testing.T) {
// check that iota works as expected in the const block
if NotInterested != 3 {
t.FailNow()
}
}