Length-Based Frame Stream En-/Decoding in Go I'm relatively new to Go, which is why I decided to post some code here. My goal is to en-/decode a TCP stream. The individual data packets length-based. The first two bytes are the unsigned size in little-endian byte order. The size includes the size field itself. The methods I wrote seem to en-/decode the packets as expected.

Is there a more efficient way to achieve this?
Does Go perhaps already implement such methods somewhere.



func GetPacketByLength(source io.Reader) ([]byte, error) {
    s := make([]byte, 2)
    if _, err := io.ReadFull(source, s); err != nil {
        return nil, err
    }

    // Little-endian uint16
    size := uint16(s[0]) | uint16(s[1])&lt;&lt;8 - 2

    p := make([]byte, size)
    if _, err := io.ReadFull(source, p); err != nil {
        return nil, err
    }

    return p, nil
}

func PutPacketByLength(target io.Writer, p []byte) error {
    s := make([]byte, 2)

    // Little-endian uint16
    s[0] = byte((len(p) + 2))
    s[1] = byte((len(p) + 2) &gt;&gt; 8)

    if _, err := target.Write(s); err != nil {
        return err
    }
    if _, err := target.Write(p); err != nil {
        return err
    }

    return nil
}
You may consider to use binary.Read. I find this more readable and self documented. See this example.

var len uint16
err := binary.Read(buf, binary.LittleEndian, &amp;len)


The writing part:

len := uint16(len(p))
err := binary.Write(buf, binary.LittleEndian, len)


Also don't forget to check that len(p) doesn't overflow uint16 (less than 65535).

Apart from that your code is fine.