Add some basic protocol definitions, this will be improved in the future
This commit is contained in:
parent
d7ed035ef1
commit
0866ce3579
116
protocol/protocol.go
Normal file
116
protocol/protocol.go
Normal 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
12
protocol/protocol_test.go
Normal 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()
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user