mirror of
https://git.numenor-labs.us/dsfx.git
synced 2025-04-29 16:20:34 +00:00
58 lines
1.6 KiB
Go
58 lines
1.6 KiB
Go
package buffer
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"io"
|
|
)
|
|
|
|
// MaxUint16 is the maximum value of a uint16. It is used to check if the
|
|
// length of the data is too large to be encoded in a uint16.
|
|
const MaxUint16 = 0xFFFF
|
|
|
|
// ErrInvalidLength is the error message returned when the length of the data
|
|
// is too large to be encoded in a uint16.
|
|
var ErrInvalidLength = errors.New("data length is too large to be encoded in a uint16")
|
|
|
|
// NewLenPrefixed returns a new buffer with a length prefix. The length prefix is
|
|
// 2 bytes long and is encoded in big-endian order. The length prefix is
|
|
// followed by the data.
|
|
func NewLenPrefixed(data []byte) ([]byte, error) {
|
|
length := len(data)
|
|
// Overflow Guard: If the length of the data is greater than the maximum
|
|
// value of a uint16, return an error.
|
|
if length > MaxUint16 {
|
|
return nil, ErrInvalidLength
|
|
}
|
|
buf := make([]byte, 2+len(data))
|
|
binary.BigEndian.PutUint16(buf, uint16(len(data)))
|
|
copy(buf[2:], data)
|
|
return buf, nil
|
|
}
|
|
|
|
func ReadLenPrefixed(maxSize uint16, r io.Reader) ([]byte, error) {
|
|
lenBuf := make([]byte, 2)
|
|
if _, err := io.ReadFull(r, lenBuf); err != nil {
|
|
return nil, err
|
|
}
|
|
if len(lenBuf) < 2 {
|
|
return nil, errors.New("buffer is too small to contain length prefix")
|
|
}
|
|
length := binary.BigEndian.Uint16(lenBuf)
|
|
|
|
if length > maxSize {
|
|
return nil, errors.New("data length is too large to be encoded in a uint16")
|
|
}
|
|
|
|
buf := make([]byte, length)
|
|
if _, err := io.ReadFull(r, buf); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(buf) < int(length) {
|
|
return nil, errors.New("buffer is too small to contain data")
|
|
}
|
|
|
|
return buf, nil
|
|
}
|