Ejemplo n.º 1
0
// Modified from http://golang.org/src/pkg/encoding/binary/varint.go#106
func readVarint32(dst io.Writer, src io.Reader) (int32, int, error) {
	var x int32
	var s uint
	var i int
	var buf [4]byte

	for i = 0; i < 4; i++ {
		_, err := src.Read(buf[i : i+1])
		if err != nil {
			return 0, i + 1, err
		}

		if buf[i] < 0x80 {
			x |= int32(buf[i]) << s
			break
		}

		x |= int32(buf[i]&0x7f) << s
		s += 7
	}

	if i > 3 || (i == 3 && buf[3]&0x80 > 0) {
		return x, i + 1, glog.NewError("Malformed remaining length. 4th byte has continuation bit set.")
	}

	if dst != nil {
		if n, err := dst.Write(buf[:i+1]); err != nil {
			return x, n, glog.NewError("Error writing data: %v", err)
		}
	}

	return x, i + 1, nil
}
Ejemplo n.º 2
0
func readUint16(buf *bytes.Buffer) (uint16, error) {
	if buf.Len() < 2 {
		return 0, glog.NewError("Insufficient buffer size. Expecting %d, got %d.", 2, buf.Len())
	}

	return binary.BigEndian.Uint16(buf.Next(2)), nil
}
Ejemplo n.º 3
0
func (this *fixedHeader) copy(src io.Reader) (int64, error) {
	total, err := io.CopyN(this.buf, src, 1)
	if err != nil {
		return 0, err
	}

	b, err := this.buf.ReadByte()
	if err != nil {
		return 0, err
	}

	mtype := MessageType(b >> 4)
	if !mtype.Valid() {
		return total, glog.NewError("Invalid message type %d.", mtype)
	}

	if mtype != this.mtype {
		return total, glog.NewError("Invalid message type %d. Expecting %d.", mtype, this.mtype)
	}

	this.flags = b & 0x0f
	if this.mtype != PUBLISH && this.flags != this.mtype.DefaultFlags() {
		return total, glog.NewError("Invalid message (%d) flags. Expecting %d, got %d", this.mtype, this.mtype.DefaultFlags, this.flags)
	}

	if this.mtype == PUBLISH && !ValidQos((this.flags>>1)&0x3) {
		return total, glog.NewError("Invalid QoS (%d) for PUBLISH message.", (this.flags>>1)&0x3)
	}

	var m int
	this.remlen, m, err = readVarint32(this.buf, src)
	if err != nil {
		return total + int64(m), err
	}
	total += int64(m)
	this.buf.Next(m)

	n, err := io.CopyN(this.buf, src, int64(this.remlen))
	if err != nil {
		return total + n, err
	}

	return total, nil
}
Ejemplo n.º 4
0
func writeVarint32(dst io.Writer, x int32) (int, error) {
	if x > maxRemainingLength {
		return 0, glog.NewError("Exceeded maximum of %d", maxRemainingLength)
	}

	var buf [4]byte
	i := 0

	for x >= 0x80 {
		buf[i] = byte(x) | 0x80
		x >>= 7
		i++
	}
	buf[i] = byte(x)

	n, err := dst.Write(buf[:i+1])
	if err != nil {
		return n, glog.NewError("Error writing data: %v", err)
	}

	return n, nil
}
Ejemplo n.º 5
0
func readLPBytes(buf *bytes.Buffer) ([]byte, int, error) {
	total := 0

	n, err := readUint16(buf)
	total += 2
	if err != nil {
		return nil, total, err
	}

	if buf.Len() < int(n) {
		return nil, total, glog.NewError("Insufficient buffer size. Expecting %d, got %d.", n, buf.Len())
	}

	total += int(n)

	return buf.Next(int(n)), total, nil
}
Ejemplo n.º 6
0
func writeLPBytes(buf *bytes.Buffer, b []byte) (int, error) {
	if len(b) > int(maxLPString) {
		return 0, glog.NewError("Length greater than %d bytes.", maxLPString)
	}

	total := 0

	err := writeUint16(buf, uint16(len(b)))
	if err != nil {
		return 0, err
	}
	total += 2

	n, err := buf.Write(b)
	if err != nil {
		return total, err
	}
	total += n

	return total, nil
}