kos/entry/cli/frame.go

155 lines
3.1 KiB
Go
Raw Permalink Normal View History

2023-04-23 17:57:36 +08:00
package cli
import (
"bytes"
"encoding/binary"
"io"
"math"
"time"
)
const (
PacketTypeCompleter byte = 0x01
PacketTypeCommand = 0x02
PacketTypeHandshake = 0x03
)
const (
FlagPortion = 0x00
FlagComplete = 0x01
)
type (
Frame struct {
Feature []byte
Type byte `json:"type"`
Flag byte `json:"flag"`
Seq uint16 `json:"seq"`
Data []byte `json:"data"`
Error string `json:"error"`
Timestamp int64 `json:"timestamp"`
}
)
func readFrame(r io.Reader) (frame *Frame, err error) {
var (
n int
dataLength uint16
errorLength uint16
errBuf []byte
)
frame = &Frame{Feature: make([]byte, 3)}
if _, err = io.ReadFull(r, frame.Feature); err != nil {
return
}
if !bytes.Equal(frame.Feature, Feature) {
err = io.ErrUnexpectedEOF
return
}
if err = binary.Read(r, binary.LittleEndian, &frame.Type); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &frame.Flag); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &frame.Seq); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &frame.Timestamp); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &dataLength); err != nil {
return
}
if err = binary.Read(r, binary.LittleEndian, &errorLength); err != nil {
return
}
if dataLength > 0 {
frame.Data = make([]byte, dataLength)
if n, err = io.ReadFull(r, frame.Data); err == nil {
if n < int(dataLength) {
err = io.ErrShortBuffer
}
}
}
if errorLength > 0 {
errBuf = make([]byte, errorLength)
if n, err = io.ReadFull(r, errBuf); err == nil {
if n < int(dataLength) {
err = io.ErrShortBuffer
} else {
frame.Error = string(errBuf)
}
}
}
return
}
func writeFrame(w io.Writer, frame *Frame) (err error) {
var (
n int
dl int
dataLength uint16
errorLength uint16
errBuf []byte
)
if _, err = w.Write(Feature); err != nil {
return
}
if frame.Data != nil {
dl = len(frame.Data)
if dl > math.MaxUint16 {
return io.ErrNoProgress
}
dataLength = uint16(dl)
}
if frame.Error != "" {
errBuf = []byte(frame.Error)
errorLength = uint16(len(errBuf))
}
if err = binary.Write(w, binary.LittleEndian, frame.Type); err != nil {
return
}
if err = binary.Write(w, binary.LittleEndian, frame.Flag); err != nil {
return
}
if err = binary.Write(w, binary.LittleEndian, frame.Seq); err != nil {
return
}
if err = binary.Write(w, binary.LittleEndian, frame.Timestamp); err != nil {
return
}
if err = binary.Write(w, binary.LittleEndian, dataLength); err != nil {
return
}
if err = binary.Write(w, binary.LittleEndian, errorLength); err != nil {
return
}
if dataLength > 0 {
if n, err = w.Write(frame.Data); err == nil {
if n < int(dataLength) {
err = io.ErrShortWrite
}
}
}
if errorLength > 0 {
if n, err = w.Write(errBuf); err == nil {
if n < int(errorLength) {
err = io.ErrShortWrite
}
}
}
return
}
func newFrame(t, f byte, seq uint16, data []byte) *Frame {
return &Frame{
Feature: Feature,
Type: t,
Flag: f,
Seq: seq,
Data: data,
Timestamp: time.Now().Unix(),
}
}