func Unpack(b []byte, elts ...interface{}) (int, error) {
	buf := bytes.NewBuffer(b)
	err := UnpackBuf(buf, elts...)
	read := len(b) - buf.Len()
	return read, err
}
Unpack is a convenience wrapper around UnpackBuf. Unpack returns the number
of bytes read from b to fill elts and error, if any.
package tpmutil
import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"reflect"
)
var (
	selfMarshalerType = reflect.TypeOf((*SelfMarshaler)(nil)).Elem()
	handlesAreaType   = reflect.TypeOf((*[]Handle)(nil))
)
func packWithHeader(ch commandHeader, cmd ...interface{}) ([]byte, error) {
	hdrSize := binary.Size(ch)
	body, err := Pack(cmd...)
	if err != nil {
		return nil, fmt.Errorf("couldn't pack message body: %v", err)
	}
	bodySize := len(body)
	ch.Size = uint32(hdrSize + bodySize)
	header, err := Pack(ch)
	if err != nil {
		return nil, fmt.Errorf("couldn't pack message header: %v", err)
	}
	return append(header, body...), nil
}
func Pack(elts ...interface{}) ([]byte, error) {
	buf := new(bytes.Buffer)
	if err := packType(buf, elts...); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
func tryMarshal(buf io.Writer, v reflect.Value) (bool, error) {
	t := v.Type()
	if t.Implements(selfMarshalerType) {
		if v.Kind() == reflect.Ptr && v.IsNil() {
			return true, fmt.Errorf("cannot call TPMMarshal on a nil pointer of type %T", v)
		}
		return true, v.Interface().(SelfMarshaler).TPMMarshal(buf)
	}
	if reflect.PtrTo(t).Implements(selfMarshalerType) {
		tmp := reflect.New(t)
		tmp.Elem().Set(v)
		return true, tmp.Interface().(SelfMarshaler).TPMMarshal(buf)
	}
	return false, nil
}
func packValue(buf io.Writer, v reflect.Value) error {
	if v.Type() == handlesAreaType {
		v = v.Convert(reflect.TypeOf((*handleList)(nil)))
	}
	if canMarshal, err := tryMarshal(buf, v); canMarshal {
		return err
	}
	switch v.Kind() {
	case reflect.Ptr:
		if v.IsNil() {
			return fmt.Errorf("cannot pack nil %s", v.Type().String())
		}
		return packValue(buf, v.Elem())
	case reflect.Struct:
		for i := 0; i < v.NumField(); i++ {
			f := v.Field(i)
			if err := packValue(buf, f); err != nil {
				return err
			}
		}
	default:
		return binary.Write(buf, binary.BigEndian, v.Interface())
	}
	return nil
}
func packType(buf io.Writer, elts ...interface{}) error {
	for _, e := range elts {
		if err := packValue(buf, reflect.ValueOf(e)); err != nil {
			return err
		}
	}
	return nil
}
func tryUnmarshal(buf io.Reader, v reflect.Value) (bool, error) {
	t := v.Type()
	if t.Implements(selfMarshalerType) {
		if v.Kind() == reflect.Ptr && v.IsNil() {
			return true, fmt.Errorf("cannot call TPMUnmarshal on a nil pointer")
		}
		return true, v.Interface().(SelfMarshaler).TPMUnmarshal(buf)
	}
	if v.CanAddr() && reflect.PtrTo(t).Implements(selfMarshalerType) {
		return true, v.Addr().Interface().(SelfMarshaler).TPMUnmarshal(buf)
	}
	return false, nil
}