maeqtt/mqtt/types/Encoding.go

87 lines
1.5 KiB
Go

package types
import (
"encoding/binary"
"errors"
"io"
)
func WriteBits(w io.Writer, data [8]bool) error {
encoded := byte(0)
for i, v := range data {
encoded = encoded | byte(BoolToUint(v)<<i)
}
_, err := w.Write([]byte{encoded})
return err
}
func WriteUint16(w io.Writer, v uint16) error {
buf := make([]byte, 2)
binary.BigEndian.PutUint16(buf, v)
_, err := w.Write(buf)
return err
}
func WriteUint32(w io.Writer, v uint32) error {
buf := make([]byte, 4)
binary.BigEndian.PutUint32(buf, v)
_, err := w.Write(buf)
return err
}
const uint32Max uint32 = ^uint32(0)
func WriteDataWithVarIntLen(w io.Writer, data []byte) error {
if len(data) > int(uint32Max) {
return errors.New("Tried to write more data than max varint size")
}
err := WriteVariableByteInt(w, uint32(len(data)))
if err != nil {
return err
}
_, err = w.Write(data)
return err
}
const uint16Max uint16 = ^uint16(0)
func WriteBinaryData(w io.Writer, data []byte) error {
if len(data) > int(uint16Max) {
return errors.New("Tried to write more data than max uint16 size")
}
err := WriteUint16(w, uint16(len(data)))
if err != nil {
return err
}
_, err = w.Write(data)
return err
}
func WriteUTF8String(w io.Writer, str string) error {
return WriteBinaryData(w, []byte(str))
}
func WriteVariableByteInt(w io.Writer, v uint32) error {
for {
encodedByte := byte(v % 128)
v = v / 128
if v > 0 {
encodedByte = encodedByte | 128
}
_,err := w.Write([]byte{encodedByte})
if err != nil {
return err
}
if v == 0 {
return nil
}
}
}