mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-06 00:25:43 +00:00
144 lines
2.6 KiB
Go
144 lines
2.6 KiB
Go
package message
|
|
|
|
import (
|
|
"encoding/binary"
|
|
)
|
|
|
|
// message ID
|
|
type ID byte
|
|
|
|
const (
|
|
IdChoke ID = iota
|
|
IdUnchoke
|
|
IdInterested
|
|
IdNotInterested
|
|
IdHave
|
|
IdBitfield
|
|
IdRequest
|
|
IdPiece
|
|
IdCancel
|
|
)
|
|
|
|
/*type Message struct {
|
|
Length uint32
|
|
ID MessageID
|
|
Payload []byte
|
|
}*/
|
|
|
|
type base struct {
|
|
id ID
|
|
}
|
|
|
|
func (base *base) ID() ID {
|
|
return base.id
|
|
}
|
|
|
|
func (base *base) Encode() []byte {
|
|
return encode(base, nil)
|
|
}
|
|
|
|
func (base *base) Decode(body []byte) {
|
|
|
|
}
|
|
|
|
type Message interface {
|
|
ID() ID
|
|
Encode() []byte
|
|
Decode(body []byte)
|
|
}
|
|
|
|
type TestMsg struct {
|
|
*base
|
|
}
|
|
|
|
func (base *TestMsg) Encode() []byte {
|
|
return []byte{1, 2, 3}
|
|
}
|
|
|
|
func (base *TestMsg) Decode(body []byte) {
|
|
}
|
|
|
|
func encode(base *base, body []byte) []byte {
|
|
buf := make([]byte, 5+len(body))
|
|
binary.BigEndian.PutUint32(buf, uint32(len(buf)))
|
|
buf[4] = byte(base.id)
|
|
copy(buf[4:], body)
|
|
return buf
|
|
}
|
|
|
|
/*func Decode(buf []byte) Message {
|
|
head := make([]byte, 5)
|
|
body := message.Encode()
|
|
binary.BigEndian.PutUint32(head, uint32(len(head)+len(body)))
|
|
head[4] = byte(message.ID())
|
|
return append(head, body...)
|
|
}
|
|
|
|
func (msg *Message) ToBytes() []byte {
|
|
buf := make([]byte, 5)
|
|
binary.BigEndian.PutUint32(buf, msg.Length)
|
|
buf[4] = byte(msg.ID)
|
|
if msg.Payload != nil {
|
|
return append(buf, msg.Payload.Encode()...)
|
|
} else {
|
|
return buf
|
|
}
|
|
}
|
|
|
|
func (msg *Message) FormBytes(buf []byte) {
|
|
msg.Length = binary.BigEndian.Uint32(buf)
|
|
msg.ID = ID(buf[4])
|
|
if msg.Payload != nil {
|
|
msg.Payload.Decode(buf[4:])
|
|
}
|
|
}*/
|
|
|
|
/*func NewMessage(id MessageID, Payload []byte) *Message {
|
|
message := &Message{ID: id, Payload: Payload}
|
|
if id == Keepalive {
|
|
message.Length = 0
|
|
} else {
|
|
message.Length = uint32(len(Payload) + 1)
|
|
}
|
|
return message
|
|
}
|
|
|
|
func (msg *Message) Encode() []byte {
|
|
if msg.ID == Keepalive {
|
|
return make([]byte, 4)
|
|
} else {
|
|
buf := make([]byte, 5+len(msg.Payload))
|
|
binary.BigEndian.PutUint32(buf, msg.Length)
|
|
buf[4] = byte(msg.ID)
|
|
copy(buf[5:], msg.Payload[:])
|
|
return buf
|
|
}
|
|
}
|
|
|
|
func (msg *Message) Decode(buf []byte) {
|
|
msg.Length = binary.BigEndian.Uint32(buf)
|
|
if msg.Length == 0 {
|
|
msg.ID = -1
|
|
} else {
|
|
msg.ID = MessageID(buf[4])
|
|
if msg.Length > 4 {
|
|
msg.Payload = buf[5:]
|
|
}
|
|
}
|
|
}*/
|
|
|
|
// Message protocol
|
|
// Length prefix| message ID | Payload
|
|
// 4-byte | 1-byte | remaining bytes
|
|
// 100 | 5 | 99-bytes
|
|
// https://wiki.theory.org/index.php/BitTorrentSpecification#Messages
|
|
func SplitMessage(data []byte, atEOF bool) (advance int, token []byte, err error) {
|
|
if !atEOF && len(data) > 4 {
|
|
length := int(binary.BigEndian.Uint32(data))
|
|
if len(data)-4 >= length {
|
|
return length + 4, data[:length+4], nil
|
|
}
|
|
}
|
|
return
|
|
}
|