package protocol
import (
"encoding/binary"
"errors"
"io"
)
type FrameType byte
const (
TypeAttach FrameType = iota + 1
TypeSnapshot
TypeOutput
TypeInput
TypeResize
TypeHop
TypeInfo
TypeInfoResp
TypeKill
)
func ReadFrame(r io.Reader) (FrameType, []byte, error) {
var h [5]byte
if _, err := io.ReadFull(r, h[:]); err != nil {
return 0, nil, err
}
n := binary.BigEndian.Uint32(h[1:5])
if n > 16<<20 {
return 0, nil, errors.New("frame too large")
}
p := make([]byte, n)
if _, err := io.ReadFull(r, p); err != nil {
return 0, nil, err
}
return FrameType(h[0]), p, nil
}
func WriteFrame(w io.Writer, t FrameType, payload []byte) error {
_, err := w.Write(append(binary.BigEndian.AppendUint32([]byte{byte(t)}, uint32(len(payload))), payload...))
return err
}
func EncodeSize(c, r int) []byte {
return binary.BigEndian.AppendUint16(binary.BigEndian.AppendUint16(nil, uint16(c)), uint16(r))
}
func DecodeSize(b []byte) (int, int, error) {
if len(b) < 4 {
return 80, 24, errors.New("short size")
}
return int(binary.BigEndian.Uint16(b[:2])), int(binary.BigEndian.Uint16(b[2:4])), nil
}