func (m *Message) decodeSection(data []byte) (int, error) {
	section := NewMessage()
	buf := bytes.NewBuffer(data)
	n, err := buf.ReadByte()
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	keyLen := int(n)
	key := string(buf.Next(keyLen))
	if len(key) != keyLen {
		return -1, errBadKey
	}
	b, err := buf.ReadByte()
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	count := keyLen + 2
	for b != msgSectionEnd {
		switch b {
		case msgKeyValue:
			n, err := section.decodeKeyValue(buf.Bytes())
			if err != nil {
				return -1, err
			}
			buf.Next(n)
			count += n
		case msgListStart:
			n, err := section.decodeList(buf.Bytes())
			if err != nil {
				return -1, err
			}
			buf.Next(n)
			count += n
		case msgSectionStart:
			n, err := section.decodeSection(buf.Bytes())
			if err != nil {
				return -1, err
			}
			buf.Next(n)
			count += n
		default:
			return -1, errExpectedBeginning
		}
		b, err = buf.ReadByte()
		if err != nil {
			return -1, fmt.Errorf("%v: %v", errDecoding, err)
		}
		count++
	}
	err = m.addItem(key, section)
	if err != nil {
		return -1, err
	}
	return count, nil
}
decodeSection will decode a section into a message's data, and return the number
of bytes decoded.
package vici
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"reflect"
	"strconv"
	"strings"
)
const (
	msgSectionStart uint8 = iota + 1
	msgSectionEnd
	msgKeyValue
	msgListStart
	msgListItem
	msgListEnd
)
var (
	errEncoding  = errors.New("vici: error encoding message")
	errDecoding  = errors.New("vici: error decoding message")
	errMarshal   = errors.New("vici: error marshaling message")
	errUnmarshal = errors.New("vici: error unmarshaling message")
	errUnsupportedType = errors.New("vici: unsupported message element type")
	errCommandFailed = errors.New("vici: command failed")
	errMalformedMessage = errors.New("vici: malformed message")
	errBadKey            = fmt.Errorf("%v: expected key length does not match actual length", errMalformedMessage)
	errBadValue          = fmt.Errorf("%v: expected value length does not match actual length", errMalformedMessage)
	errEndOfBuffer       = fmt.Errorf("%v: unexpected end of buffer", errMalformedMessage)
	errExpectedBeginning = fmt.Errorf("%v: expected beginning of message element", errMalformedMessage)
	errMarshalUnsupportedType = fmt.Errorf("%v: encountered unsupported type", errMarshal)
	errUnmarshalBadType         = fmt.Errorf("%v: type must be non-nil pointer or map", errUnmarshal)
	errUnmarshalTypeMismatch    = fmt.Errorf("%v: incompatible types", errUnmarshal)
	errUnmarshalNonMessage      = fmt.Errorf("%v: encountered non-message type", errUnmarshal)
	errUnmarshalUnsupportedType = fmt.Errorf("%v: encountered unsupported type", errUnmarshal)
	errUnmarshalParseFailure    = fmt.Errorf("%v: failed to parse value", errUnmarshal)
)
type MessageStream struct {
	messages []*Message
}
func NewMessageStream(messages ...*Message) *MessageStream {
	return &MessageStream{messages: messages}
}
func (ms *MessageStream) Messages() []*Message {
	return ms.messages
}
type Message struct {
	keys []string
	data map[string]interface{}
}
func NewMessage() *Message {
	return &Message{
		keys: make([]string, 0),
		data: make(map[string]interface{}),
	}
}
func MarshalMessage(v interface{}) (*Message, error) {
	m := NewMessage()
	if err := m.marshal(v); err != nil {
		return nil, err
	}
	return m, nil
}
func UnmarshalMessage(m *Message, v interface{}) error {
	return m.unmarshal(v)
}
func (m *Message) Set(key string, value interface{}) error {
	return m.marshalField(key, reflect.ValueOf(value))
}
func (m *Message) Unset(key string) {
	for i, v := range m.keys {
		if v != key {
			continue
		}
		m.keys = append(m.keys[:i], m.keys[i+1:]...)
		delete(m.data, key)
		return
	}
}
func (m *Message) Get(key string) interface{} {
	v, ok := m.data[key]
	if !ok {
		return nil
	}
	return v
}
func (m *Message) Keys() []string {
	keys := make([]string, len(m.keys))
	copy(keys, m.keys)
	return keys
}
func (m *Message) Err() error {
	if success, ok := m.data["success"]; ok {
		if success != "yes" {
			return fmt.Errorf("%v: %v", errCommandFailed, m.data["errmsg"])
		}
	}
	return nil
}
func (m *Message) addItem(key string, value interface{}) error {
	_, exists := m.data[key]
	switch v := value.(type) {
	case string:
		m.data[key] = v
	case []string:
		m.data[key] = v
	case *Message:
		m.data[key] = v
	default:
		return errUnsupportedType
	}
	if !exists {
		m.keys = append(m.keys, key)
	}
	return nil
}
type messageElement struct {
	k string
	v interface{}
}
func (m *Message) elements() []messageElement {
	ordered := make([]messageElement, len(m.keys))
	for i, k := range m.keys {
		ordered[i] = messageElement{k: k, v: m.data[k]}
	}
	return ordered
}
func (m *Message) encode() ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})
	for _, e := range m.elements() {
		k := e.k
		v := e.v
		rv := reflect.ValueOf(v)
		var (
			data []byte
			err  error
		)
		switch rv.Kind() {
		case reflect.String:
			uv := v.(string)
			data, err = m.encodeKeyValue(k, uv)
			if err != nil {
				return nil, err
			}
		case reflect.Slice, reflect.Array:
			uv := v.([]string)
			data, err = m.encodeList(k, uv)
			if err != nil {
				return nil, err
			}
		case reflect.Ptr:
			uv, ok := v.(*Message)
			if !ok {
				return nil, errUnsupportedType
			}
			data, err = m.encodeSection(k, uv)
			if err != nil {
				return nil, err
			}
		default:
			return nil, errUnsupportedType
		}
		_, err = buf.Write(data)
		if err != nil {
			return nil, fmt.Errorf("%v: %v", errEncoding, err)
		}
	}
	return buf.Bytes(), nil
}
func (m *Message) decode(data []byte) error {
	buf := bytes.NewBuffer(data)
	b, err := buf.ReadByte()
	if err != nil && err != io.EOF {
		return fmt.Errorf("%v: %v", errDecoding, err)
	}
	for buf.Len() > 0 {
		switch b {
		case msgKeyValue:
			n, err := m.decodeKeyValue(buf.Bytes())
			if err != nil {
				return err
			}
			buf.Next(n)
		case msgListStart:
			n, err := m.decodeList(buf.Bytes())
			if err != nil {
				return err
			}
			buf.Next(n)
		case msgSectionStart:
			n, err := m.decodeSection(buf.Bytes())
			if err != nil {
				return err
			}
			buf.Next(n)
		}
		b, err = buf.ReadByte()
		if err != nil && err != io.EOF {
			return fmt.Errorf("%v: %v", errDecoding, err)
		}
	}
	return nil
}
func (m *Message) encodeKeyValue(key, value string) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{msgKeyValue})
	err := buf.WriteByte(uint8(len(key)))
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	_, err = buf.WriteString(key)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	vl := make([]byte, 2)
	binary.BigEndian.PutUint16(vl, uint16(len(value)))
	_, err = buf.Write(vl)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	_, err = buf.WriteString(value)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	return buf.Bytes(), nil
}
func (m *Message) encodeList(key string, list []string) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{msgListStart})
	err := buf.WriteByte(uint8(len(key)))
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	_, err = buf.WriteString(key)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	for _, item := range list {
		err = buf.WriteByte(msgListItem)
		if err != nil {
			return nil, fmt.Errorf("%v: %v", errEncoding, err)
		}
		il := make([]byte, 2)
		binary.BigEndian.PutUint16(il, uint16(len(item)))
		_, err = buf.Write(il)
		if err != nil {
			return nil, fmt.Errorf("%v: %v", errEncoding, err)
		}
		_, err = buf.WriteString(item)
		if err != nil {
			return nil, fmt.Errorf("%v: %v", errEncoding, err)
		}
	}
	err = buf.WriteByte(msgListEnd)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	return buf.Bytes(), nil
}
func (m *Message) encodeSection(key string, section *Message) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{msgSectionStart})
	err := buf.WriteByte(uint8(len(key)))
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	_, err = buf.WriteString(key)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	for _, e := range section.elements() {
		k := e.k
		v := e.v
		rv := reflect.ValueOf(v)
		var data []byte
		switch rv.Kind() {
		case reflect.String:
			uv := v.(string)
			data, err = m.encodeKeyValue(k, uv)
			if err != nil {
				return nil, err
			}
		case reflect.Slice, reflect.Array:
			uv := v.([]string)
			data, err = m.encodeList(k, uv)
			if err != nil {
				return nil, err
			}
		case reflect.Ptr:
			uv, ok := v.(*Message)
			if !ok {
				return nil, errUnsupportedType
			}
			data, err = m.encodeSection(k, uv)
			if err != nil {
				return nil, err
			}
		default:
			return nil, errUnsupportedType
		}
		_, err = buf.Write(data)
		if err != nil {
			return nil, fmt.Errorf("%v: %v", errEncoding, err)
		}
	}
	err = buf.WriteByte(msgSectionEnd)
	if err != nil {
		return nil, fmt.Errorf("%v: %v", errEncoding, err)
	}
	return buf.Bytes(), nil
}
func (m *Message) decodeKeyValue(data []byte) (int, error) {
	buf := bytes.NewBuffer(data)
	n, err := buf.ReadByte()
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	keyLen := int(n)
	key := string(buf.Next(keyLen))
	if len(key) != keyLen {
		return -1, errBadKey
	}
	v := buf.Next(2)
	if len(v) != 2 {
		return -1, errEndOfBuffer
	}
	valueLen := int(binary.BigEndian.Uint16(v))
	value := string(buf.Next(valueLen))
	if len(value) != valueLen {
		return -1, errBadValue
	}
	err = m.addItem(key, value)
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	return keyLen + valueLen + 3, nil
}
func (m *Message) decodeList(data []byte) (int, error) {
	var list []string
	buf := bytes.NewBuffer(data)
	n, err := buf.ReadByte()
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	keyLen := int(n)
	key := string(buf.Next(keyLen))
	if len(key) != keyLen {
		return -1, errBadKey
	}
	b, err := buf.ReadByte()
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	count := keyLen + 2
	for b != msgListEnd {
		if b != msgListItem {
			return -1, errExpectedBeginning
		}
		v := buf.Next(2)
		if len(v) != 2 {
			return -1, errEndOfBuffer
		}
		valueLen := int(binary.BigEndian.Uint16(v))
		value := string(buf.Next(valueLen))
		if len(value) != valueLen {
			return -1, errBadValue
		}
		list = append(list, value)
		b, err = buf.ReadByte()
		if err != nil {
			return -1, fmt.Errorf("%v: %v", errDecoding, err)
		}
		count += valueLen + 3
	}
	err = m.addItem(key, list)
	if err != nil {
		return -1, fmt.Errorf("%v: %v", errDecoding, err)
	}
	return count, nil
}