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 }