91 lines
1.8 KiB
Go
Raw Normal View History

2024-12-28 01:59:13 +01:00
package main
2024-12-28 03:31:45 +01:00
import (
"encoding/binary"
"io"
)
2024-12-28 01:59:13 +01:00
type Typed interface {
Type() uint32
}
type Framed interface {
Value() []byte
}
type Frame interface {
Typed
Framed
}
type frame struct {
2024-12-28 03:31:45 +01:00
typeID uint32
valueBytes []byte
2024-12-28 01:59:13 +01:00
}
func (f frame) Type() uint32 {
2024-12-28 03:31:45 +01:00
return f.typeID
2024-12-28 01:59:13 +01:00
}
func (f frame) Value() []byte {
2024-12-28 03:31:45 +01:00
return f.valueBytes
2024-12-28 01:59:13 +01:00
}
2024-12-28 03:31:45 +01:00
// FrameReadWriter is a struct encapsulating io.ReadWriter, which provides additional methods for reading and
// writing frames -- messages which have their own type and value byte buffer.
// Data sent or received using this socket is expected to be encoded in LTV format, which means:
// L - 4 bytes of frame length, big endian encoded
// T - 4 bytes of frame type, big endian encoded
// V - L bytes of frame data bytes
2024-12-28 01:59:13 +01:00
type FrameReadWriter struct {
2024-12-28 03:31:45 +01:00
io.ReadWriter
2024-12-28 01:59:13 +01:00
}
2024-12-28 03:31:45 +01:00
func (frw FrameReadWriter) ReadFrame() (Frame, error) {
lengthBytes := make([]byte, 4)
_, err := io.ReadFull(frw, lengthBytes)
if err != nil {
return nil, err
}
frameLength := binary.BigEndian.Uint32(lengthBytes)
typeBytes := make([]byte, 4)
_, err = io.ReadFull(frw, typeBytes)
if err != nil {
return nil, err
}
frameType := binary.LittleEndian.Uint32(typeBytes)
frameBytes := make([]byte, frameLength)
_, err = io.ReadFull(frw, frameBytes)
if err != nil {
return nil, err
}
result := frame{typeID: frameType, valueBytes: frameBytes}
return result, nil
2024-12-28 01:59:13 +01:00
}
2024-12-28 03:31:45 +01:00
func (frw FrameReadWriter) WriteFrame(f Frame) error {
frameLength := len(f.Value())
lengthBytes := make([]byte, 4)
binary.BigEndian.PutUint32(lengthBytes, uint32(frameLength))
typeBytes := make([]byte, 4)
binary.BigEndian.PutUint32(typeBytes, f.Type())
result := make([]byte, 0)
result = append(result, lengthBytes...)
result = append(result, typeBytes...)
result = append(result, f.Value()...)
_, err := frw.Write(result)
if err != nil {
return err
}
2024-12-28 01:59:13 +01:00
return nil
}