package protocol

import "io"
import "fmt"

// ReadBuf reads a size-prefixed buffer.
func ReadBuf (sizeBytes int, reader io.Reader) (buf []byte, err error) {
	size, err := ReadInt(reader, sizeBytes)
	if err != nil { return nil, err }
	buf = make([]byte, size)
	_, err = io.ReadFull(reader, buf)
	return buf, err
}

// ReadBuf8 reads a size-prefixed buffer with an 8-bit size.
func ReadBuf8 (reader io.Reader) (buf []byte, err error) {
	return ReadBuf(1, reader)
}

// ReadBuf16 reads a size-prefixed buffer with a 16-bit size.
func ReadBuf16 (reader io.Reader) (buf []byte, err error) {
	return ReadBuf(2, reader)
}

// ReadString reads a size-prefixed string.
func ReadString (sizeBytes int, reader io.Reader) (str string, err error) {
	buf, err := ReadBuf(sizeBytes, reader)
	return string(buf), err
}

// ReadString8 reads a size-prefixed string with an 8-bit size.
func ReadString8 (reader io.Reader) (str string, err error) {
	return ReadString(1, reader)
}

// ReadString16 reads a size-prefixed string with a 16-bit size.
func ReadString16 (reader io.Reader) (str string, err error) {
	return ReadString(2, reader)
}

func WriteBuf (writer io.Writer, sizeBytes int, buf []byte) (err error) {
	if uint(len(buf)) > MaxIntOfSize(sizeBytes) {
		panic(fmt.Sprintf("len %d cannot fit in U%d", len(buf), sizeBytes * 8))
	}

	err = WriteInt(writer, sizeBytes, uint(len(buf)))
	if err != nil { return }
	_, err = writer.Write(buf)
	return
}

func WriteBuf8 (writer io.Writer, buf []byte) error {
	return WriteBuf(writer, 1, buf)
}

func WriteBuf16 (writer io.Writer, buf []byte) error {
	return WriteBuf(writer, 2, buf)
}

func WriteString (writer io.Writer, sizeBytes int, str string) (err error) {
	return WriteBuf(writer, sizeBytes, []byte(str))
}

func WriteString8 (writer io.Writer, str string) (err error) {
	return WriteBuf8(writer, []byte(str))
}

func WriteString16 (writer io.Writer, str string) (err error) {
	return WriteBuf16(writer, []byte(str))
}
