func (enc *Encoder) EncodeString(v string) (int, error) {
	n, err := enc.EncodeUint(uint32(len(v)))
	if err != nil {
		return n, err
	}
	n2, err := enc.EncodeFixedOpaque([]byte(v))
	n += n2
	return n, err
}
EncodeString writes the XDR encoded representation of the passed string
to the encapsulated writer and returns the number of bytes written.
Character encoding is assumed to be UTF-8 and therefore ASCII compatible.  If
the underlying character encoding is not compatible with this assumption, the
data can instead be written as variable-length opaque data (EncodeOpaque) and
manually converted as needed.

A MarshalError with an error code of ErrIO is returned if writing the data
fails.

Reference:
RFC Section 4.11 - String
Unsigned integer length followed by bytes zero-padded to a multiple of four
package xdr
import (
	"fmt"
	"io"
	"math"
	"reflect"
	"time"
)
var errIOEncode = "%s while encoding %d bytes"
func Marshal(w io.Writer, v interface{}) (int, error) {
	enc := Encoder{w: w}
	return enc.Encode(v)
}
type Encoder struct {
	w io.Writer
}
func (enc *Encoder) EncodeInt(v int32) (int, error) {
	var b [4]byte
	b[0] = byte(v >> 24)
	b[1] = byte(v >> 16)
	b[2] = byte(v >> 8)
	b[3] = byte(v)
	n, err := enc.w.Write(b[:])
	if err != nil {
		msg := fmt.Sprintf(errIOEncode, err.Error(), 4)
		err := marshalError("EncodeInt", ErrIO, msg, b[:n], err)
		return n, err
	}
	return n, nil
}
func (enc *Encoder) EncodeUint(v uint32) (int, error) {
	var b [4]byte
	b[0] = byte(v >> 24)
	b[1] = byte(v >> 16)
	b[2] = byte(v >> 8)
	b[3] = byte(v)
	n, err := enc.w.Write(b[:])
	if err != nil {
		msg := fmt.Sprintf(errIOEncode, err.Error(), 4)
		err := marshalError("EncodeUint", ErrIO, msg, b[:n], err)
		return n, err
	}
	return n, nil
}
func (enc *Encoder) EncodeEnum(v int32, validEnums map[int32]bool) (int, error) {
	if !validEnums[v] {
		err := marshalError("EncodeEnum", ErrBadEnumValue,
			"invalid enum", v, nil)
		return 0, err
	}
	return enc.EncodeInt(v)
}
func (enc *Encoder) EncodeBool(v bool) (int, error) {
	i := int32(0)
	if v == true {
		i = 1
	}
	return enc.EncodeInt(i)
}
func (enc *Encoder) EncodeHyper(v int64) (int, error) {
	var b [8]byte
	b[0] = byte(v >> 56)
	b[1] = byte(v >> 48)
	b[2] = byte(v >> 40)
	b[3] = byte(v >> 32)
	b[4] = byte(v >> 24)
	b[5] = byte(v >> 16)
	b[6] = byte(v >> 8)
	b[7] = byte(v)
	n, err := enc.w.Write(b[:])
	if err != nil {
		msg := fmt.Sprintf(errIOEncode, err.Error(), 8)
		err := marshalError("EncodeHyper", ErrIO, msg, b[:n], err)
		return n, err
	}
	return n, nil
}
func (enc *Encoder) EncodeUhyper(v uint64) (int, error) {
	var b [8]byte
	b[0] = byte(v >> 56)
	b[1] = byte(v >> 48)
	b[2] = byte(v >> 40)
	b[3] = byte(v >> 32)
	b[4] = byte(v >> 24)
	b[5] = byte(v >> 16)
	b[6] = byte(v >> 8)
	b[7] = byte(v)
	n, err := enc.w.Write(b[:])
	if err != nil {
		msg := fmt.Sprintf(errIOEncode, err.Error(), 8)
		err := marshalError("EncodeUhyper", ErrIO, msg, b[:n], err)
		return n, err
	}
	return n, nil
}
func (enc *Encoder) EncodeFloat(v float32) (int, error) {
	ui := math.Float32bits(v)
	return enc.EncodeUint(ui)
}
func (enc *Encoder) EncodeDouble(v float64) (int, error) {
	ui := math.Float64bits(v)
	return enc.EncodeUhyper(ui)
}
func (enc *Encoder) EncodeFixedOpaque(v []byte) (int, error) {
	l := len(v)
	pad := (4 - (l % 4)) % 4
	n, err := enc.w.Write(v)
	if err != nil {
		msg := fmt.Sprintf(errIOEncode, err.Error(), len(v))
		err := marshalError("EncodeFixedOpaque", ErrIO, msg, v[:n], err)
		return n, err
	}
	if pad > 0 {
		b := make([]byte, pad)
		n2, err := enc.w.Write(b)
		n += n2
		if err != nil {
			written := make([]byte, l+n2)
			copy(written, v)
			copy(written[l:], b[:n2])
			msg := fmt.Sprintf(errIOEncode, err.Error(), l+pad)
			err := marshalError("EncodeFixedOpaque", ErrIO, msg,
				written, err)
			return n, err
		}
	}
	return n, nil
}
func (enc *Encoder) EncodeOpaque(v []byte) (int, error) {
	n, err := enc.EncodeUint(uint32(len(v)))
	if err != nil {
		return n, err
	}
	n2, err := enc.EncodeFixedOpaque(v)
	n += n2
	return n, err
}