From e8d917fcef21d606a8b48a2f8cc397daac3e4017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Krzy=C5=BCanowski?= Date: Sat, 28 Dec 2024 03:31:45 +0100 Subject: [PATCH] Finish frameconn --- frameconn.go | 67 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/frameconn.go b/frameconn.go index 0c77807..ccc8f6d 100644 --- a/frameconn.go +++ b/frameconn.go @@ -1,6 +1,9 @@ package main -import "io" +import ( + "encoding/binary" + "io" +) type Typed interface { Type() uint32 @@ -16,26 +19,72 @@ type Frame interface { } type frame struct { - TypeID uint32 - ValueBytes []byte + typeID uint32 + valueBytes []byte } func (f frame) Type() uint32 { - return f.TypeID + return f.typeID } func (f frame) Value() []byte { - return f.ValueBytes + return f.valueBytes } +// 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 type FrameReadWriter struct { - rw io.ReadWriter + io.ReadWriter } -func (FrameReadWriter) ReadFrame() (Frame, error) { - return nil, nil +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 } -func (FrameReadWriter) WriteFrame(f Frame) error { +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 + } + return nil }