@@ -0,0 +1,57 @@
+// Copyright (C) 2014 Jakob Borg and other contributors. All rights reserved.
+// Use of this source code is governed by an MIT-style license that can be
+// found in the LICENSE file.
+
+package xdr_test
+import (
+ "bytes"
+ "testing"
+)
+type XDRBenchStruct struct {
+ I1 uint64
+ I2 uint32
+ I3 uint16
+ Bs []byte
+ S string
+}
+var res []byte // no to be optimized away
+var s = XDRBenchStruct{
+ I1: 42,
+ I2: 43,
+ I3: 44,
+ Bs: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18},
+ S: "Hello World!",
+var e = s.MarshalXDR()
+func BenchmarkThisMarshal(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ res = s.MarshalXDR()
+ }
+func BenchmarkThisUnmarshal(b *testing.B) {
+ var t XDRBenchStruct
+ err := t.UnmarshalXDR(e)
+ if err != nil {
+ b.Fatal(err)
+func BenchmarkEncode(b *testing.B) {
+ bs := make([]byte, 0, 65536)
+ buf := bytes.NewBuffer(bs)
+ _, err := s.EncodeXDR(buf)
+ buf.Reset()
@@ -0,0 +1,53 @@
+ "io"
+ "github.com/calmh/syncthing/xdr"
+func (o XDRBenchStruct) EncodeXDR(w io.Writer) (int, error) {
+ var xw = xdr.NewWriter(w)
+ return o.encodeXDR(xw)
+func (o XDRBenchStruct) MarshalXDR() []byte {
+ var buf bytes.Buffer
+ var xw = xdr.NewWriter(&buf)
+ o.encodeXDR(xw)
+ return buf.Bytes()
+func (o XDRBenchStruct) encodeXDR(xw *xdr.Writer) (int, error) {
+ xw.WriteUint64(o.I1)
+ xw.WriteUint32(o.I2)
+ xw.WriteUint16(o.I3)
+ xw.WriteBytes(o.Bs)
+ xw.WriteString(o.S)
+ return xw.Tot(), xw.Error()
+func (o *XDRBenchStruct) DecodeXDR(r io.Reader) error {
+ xr := xdr.NewReader(r)
+ return o.decodeXDR(xr)
+func (o *XDRBenchStruct) UnmarshalXDR(bs []byte) error {
+ var buf = bytes.NewBuffer(bs)
+ var xr = xdr.NewReader(buf)
+func (o *XDRBenchStruct) decodeXDR(xr *xdr.Reader) error {
+ o.I1 = xr.ReadUint64()
+ o.I2 = xr.ReadUint32()
+ o.I3 = xr.ReadUint16()
+ o.Bs = xr.ReadBytes()
+ o.S = xr.ReadString()
+ return xr.Error()
@@ -0,0 +1,51 @@
+ "testing/quick"
+// Contains all supported types
+type TestStruct struct {
+ I int
+ I16 int16
+ UI16 uint16
+ I32 int32
+ UI32 uint32
+ I64 int64
+ UI64 uint64
+ BS []byte
+func TestEncDec(t *testing.T) {
+ fn := func(t0 TestStruct) bool {
+ bs := t0.MarshalXDR()
+ var t1 TestStruct
+ err := t1.UnmarshalXDR(bs)
+ t.Fatal(err)
+ // Not comparing with DeepEqual since we'll unmarshal nil slices as empty
+ if t0.I != t1.I ||
+ t0.I16 != t1.I16 || t0.UI16 != t1.UI16 ||
+ t0.I32 != t1.I32 || t0.UI32 != t1.UI32 ||
+ t0.I64 != t1.I64 || t0.UI64 != t1.UI64 ||
+ bytes.Compare(t0.BS, t1.BS) != 0 ||
+ t0.S != t1.S {
+ t.Logf("%#v", t0)
+ t.Logf("%#v", t1)
+ return false
+ return true
+ if err := quick.Check(fn, nil); err != nil {
+ t.Error(err)
+func (o TestStruct) EncodeXDR(w io.Writer) (int, error) {
+func (o TestStruct) MarshalXDR() []byte {
+func (o TestStruct) encodeXDR(xw *xdr.Writer) (int, error) {
+ xw.WriteUint64(uint64(o.I))
+ xw.WriteUint16(uint16(o.I16))
+ xw.WriteUint16(o.UI16)
+ xw.WriteUint32(uint32(o.I32))
+ xw.WriteUint32(o.UI32)
+ xw.WriteUint64(uint64(o.I64))
+ xw.WriteUint64(o.UI64)
+ xw.WriteBytes(o.BS)
+func (o *TestStruct) DecodeXDR(r io.Reader) error {
+func (o *TestStruct) UnmarshalXDR(bs []byte) error {
+func (o *TestStruct) decodeXDR(xr *xdr.Reader) error {
+ o.I = int(xr.ReadUint64())
+ o.I16 = int16(xr.ReadUint16())
+ o.UI16 = xr.ReadUint16()
+ o.I32 = int32(xr.ReadUint32())
+ o.UI32 = xr.ReadUint32()
+ o.I64 = int64(xr.ReadUint64())
+ o.UI64 = xr.ReadUint64()
+ o.BS = xr.ReadBytes()
@@ -105,7 +105,7 @@ func (r *Reader) ReadUint16() uint16 {
return 0
}
- v := uint16(r.b[1]) | uint16(r.b[0])<<8
+ v := uint16(r.b[3]) | uint16(r.b[2])<<8
if debug {
dl.Debugf("@0x%x: rd uint16=%d (0x%04x)", s, v, v)
@@ -0,0 +1,45 @@
+// +build refl
+ refl "github.com/davecgh/go-xdr/xdr"
+func TestCompareMarshals(t *testing.T) {
+ e0 := s.MarshalXDR()
+ e1, err := refl.Marshal(s)
+ if bytes.Compare(e0, e1) != 0 {
+ t.Fatalf("Encoding mismatch;\n\t%x (this)\n\t%x (refl)", e0, e1)
+func BenchmarkReflMarshal(b *testing.B) {
+ var err error
+ res, err = refl.Marshal(s)
+func BenchmarkReflUnmarshal(b *testing.B) {
+ _, err := refl.Unmarshal(e, &t)
@@ -79,10 +79,10 @@ func (w *Writer) WriteUint16(v uint16) (int, error) {
dl.Debugf("wr uint16=%d", v)
- w.b[0] = byte(v >> 8)
- w.b[1] = byte(v)
- w.b[2] = 0
- w.b[3] = 0
+ w.b[0] = 0
+ w.b[1] = 0
+ w.b[2] = byte(v >> 8)
+ w.b[3] = byte(v)
var l int
l, w.err = w.w.Write(w.b[:4])