diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 5909ea93..325b3759 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -11,15 +11,18 @@ }, { "ImportPath": "github.com/calmh/du", + "Comment": "v1.0.0", "Rev": "3c0690cca16228b97741327b1b6781397afbdb24" }, { "ImportPath": "github.com/calmh/luhn", + "Comment": "v1.0.0", "Rev": "0c8388ff95fa92d4094011e5a04fc99dea3d1632" }, { "ImportPath": "github.com/calmh/xdr", - "Rev": "9eb3e1a622d9364deb39c831f7e5f164393d7e37" + "Comment": "v2.0.0", + "Rev": "b6e0c321c9b5b28ba5ee21e828323e4b982c6976" }, { "ImportPath": "github.com/golang/snappy", diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/README.md b/Godeps/_workspace/src/github.com/calmh/xdr/README.md index f4ebae78..ae9cd316 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/README.md +++ b/Godeps/_workspace/src/github.com/calmh/xdr/README.md @@ -6,7 +6,5 @@ xdr [![API Documentation](http://img.shields.io/badge/api-Godoc-blue.svg?style=flat)](http://godoc.org/github.com/calmh/xdr) [![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://opensource.org/licenses/MIT) -This is an XDR encoding/decoding library. It uses code generation and -not reflection. It supports the IPDR bastardized XDR format when built -with `-tags ipdr`. - +This is an XDR marshalling/unmarshalling library. It uses code generation and +not reflection. diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go b/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go index dbca9b7e..feebbfdf 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go +++ b/Godeps/_workspace/src/github.com/calmh/xdr/cmd/genxdr/main.go @@ -36,31 +36,73 @@ type structInfo struct { Fields []fieldInfo } -var headerTpl = template.Must(template.New("header").Parse(`// ************************************************************ +func (i structInfo) SizeExpr() string { + var xdrSizes = map[string]int{ + "int8": 4, + "uint8": 4, + "int16": 4, + "uint16": 4, + "int32": 4, + "uint32": 4, + "int64": 8, + "uint64": 8, + "int": 8, + "bool": 4, + } + + var terms []string + nl := "" + for _, f := range i.Fields { + if size := xdrSizes[f.FieldType]; size > 0 { + if f.IsSlice { + terms = append(terms, nl+"4+len(o."+f.Name+")*"+strconv.Itoa(size)) + } else { + terms = append(terms, strconv.Itoa(size)) + } + } else { + switch f.FieldType { + case "string", "[]byte": + if f.IsSlice { + terms = append(terms, nl+"4+xdr.SizeOfSlice(o."+f.Name+")") + } else { + terms = append(terms, nl+"4+len(o."+f.Name+")+xdr.Padding(len(o."+f.Name+"))") + } + default: + if f.IsSlice { + terms = append(terms, nl+"4+xdr.SizeOfSlice(o."+f.Name+")") + } else { + terms = append(terms, nl+"o."+f.Name+".XDRSize()") + } + } + } + nl = "\n" + } + return strings.Join(terms, "+") +} + +var headerData = `// ************************************************************ // This file is automatically generated by genxdr. Do not edit. // ************************************************************ package {{.Package}} import ( - "bytes" - "io" - "github.com/calmh/xdr" ) -`)) +` -var encodeTpl = template.Must(template.New("encoder").Parse(` -func (o {{.TypeName}}) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +var encoderData = ` +func (o {{.Name}}) XDRSize() int { + return {{.SizeExpr}} }//+n -func (o {{.TypeName}}) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) +func (o {{.Name}}) MarshalXDR() ([]byte, error) { + buf:= make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) }//+n -func (o {{.TypeName}}) MustMarshalXDR() []byte { +func (o {{.Name}}) MustMarshalXDR() []byte { bs, err := o.MarshalXDR() if err != nil { panic(err) @@ -68,141 +110,155 @@ func (o {{.TypeName}}) MustMarshalXDR() []byte { return bs }//+n -func (o {{.TypeName}}) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -}//+n - -func (o {{.TypeName}}) EncodeXDRInto(xw *xdr.Writer) (int, error) { - {{range $fieldInfo := .Fields}} - {{if not $fieldInfo.IsSlice}} - {{if ne $fieldInfo.Convert ""}} - xw.Write{{$fieldInfo.Encoder}}({{$fieldInfo.Convert}}(o.{{$fieldInfo.Name}})) - {{else if $fieldInfo.IsBasic}} - {{if ge $fieldInfo.Max 1}} - if l := len(o.{{$fieldInfo.Name}}); l > {{$fieldInfo.Max}} { - return xw.Tot(), xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", l, {{$fieldInfo.Max}}) - } - {{end}} - xw.Write{{$fieldInfo.Encoder}}(o.{{$fieldInfo.Name}}) - {{else}} - _, err := o.{{$fieldInfo.Name}}.EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err - } - {{end}} +func (o {{.Name}}) MarshalXDRInto(m *xdr.Marshaller) error { + {{range $fi := .Fields}} + {{if $fi.IsSlice}} + {{template "marshalSlice" $fi}} {{else}} - {{if ge $fieldInfo.Max 1}} - if l := len(o.{{$fieldInfo.Name}}); l > {{$fieldInfo.Max}} { - return xw.Tot(), xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", l, {{$fieldInfo.Max}}) - } - {{end}} - xw.WriteUint32(uint32(len(o.{{$fieldInfo.Name}}))) - for i := range o.{{$fieldInfo.Name}} { - {{if ne $fieldInfo.Convert ""}} - xw.Write{{$fieldInfo.Encoder}}({{$fieldInfo.Convert}}(o.{{$fieldInfo.Name}}[i])) - {{else if $fieldInfo.IsBasic}} - xw.Write{{$fieldInfo.Encoder}}(o.{{$fieldInfo.Name}}[i]) - {{else}} - _, err := o.{{$fieldInfo.Name}}[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err - } - {{end}} - } + {{template "marshalValue" $fi}} {{end}} {{end}} - return xw.Tot(), xw.Error() + return m.Error }//+n -func (o *{{.TypeName}}) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) -}//+n - -func (o *{{.TypeName}}) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) -}//+n - -func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error { - {{range $fieldInfo := .Fields}} - {{if not $fieldInfo.IsSlice}} - {{if ne $fieldInfo.Convert ""}} - o.{{$fieldInfo.Name}} = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}()) - {{else if $fieldInfo.IsBasic}} - {{if ge $fieldInfo.Max 1}} - o.{{$fieldInfo.Name}} = xr.Read{{$fieldInfo.Encoder}}Max({{$fieldInfo.Max}}) - {{else}} - o.{{$fieldInfo.Name}} = xr.Read{{$fieldInfo.Encoder}}() - {{end}} - {{else}} - (&o.{{$fieldInfo.Name}}).DecodeXDRFrom(xr) - {{end}} - {{else}} - _{{$fieldInfo.Name}}Size := int(xr.ReadUint32()) - if _{{$fieldInfo.Name}}Size < 0 { - return xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", _{{$fieldInfo.Name}}Size, {{$fieldInfo.Max}}) - } - {{if ge $fieldInfo.Max 1}} - if _{{$fieldInfo.Name}}Size > {{$fieldInfo.Max}} { - return xdr.ElementSizeExceeded("{{$fieldInfo.Name}}", _{{$fieldInfo.Name}}Size, {{$fieldInfo.Max}}) - } - {{end}} - o.{{$fieldInfo.Name}} = make([]{{$fieldInfo.FieldType}}, _{{$fieldInfo.Name}}Size) - for i := range o.{{$fieldInfo.Name}} { - {{if ne $fieldInfo.Convert ""}} - o.{{$fieldInfo.Name}}[i] = {{$fieldInfo.FieldType}}(xr.Read{{$fieldInfo.Encoder}}()) - {{else if $fieldInfo.IsBasic}} - {{if ge $fieldInfo.Submax 1}} - o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}Max({{$fieldInfo.Submax}}) - {{else}} - o.{{$fieldInfo.Name}}[i] = xr.Read{{$fieldInfo.Encoder}}() - {{end}} - {{else}} - (&o.{{$fieldInfo.Name}}[i]).DecodeXDRFrom(xr) - {{end}} +{{define "marshalValue"}} + {{if ne .Convert ""}} + m.Marshal{{.Encoder}}({{.Convert}}(o.{{.Name}})) + {{else if .IsBasic}} + {{if ge .Max 1}} + if l := len(o.{{.Name}}); l > {{.Max}} { + return xdr.ElementSizeExceeded("{{.Name}}", l, {{.Max}}) } {{end}} + m.Marshal{{.Encoder}}(o.{{.Name}}) + {{else}} + if err := o.{{.Name}}.MarshalXDRInto(m); err != nil { + return err + } {{end}} - return xr.Error() -}`)) +{{end}} + +{{define "marshalSlice"}} + {{if ge .Max 1}} + if l := len(o.{{.Name}}); l > {{.Max}} { + return xdr.ElementSizeExceeded("{{.Name}}", l, {{.Max}}) + } + {{end}} + + m.MarshalUint32(uint32(len(o.{{.Name}}))) + for i := range o.{{.Name}} { + {{if ne .Convert ""}} + m.Marshal{{.Encoder}}({{.Convert}}(o.{{.Name}}[i])) + {{else if .IsBasic}} + m.Marshal{{.Encoder}}(o.{{.Name}}[i]) + {{else}} + if err := o.{{.Name}}[i].MarshalXDRInto(m); err != nil { + return err + } + {{end}} + } +{{end}} + +func (o *{{.Name}}) UnmarshalXDR(bs []byte) error { + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) +} + +func (o *{{.Name}}) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + {{range $fi := .Fields}} + {{if $fi.IsSlice}} + {{template "unmarshalSlice" $fi}} + {{else}} + {{template "unmarshalValue" $fi}} + {{end}} + {{end}} + return u.Error +}//+n + +{{define "unmarshalValue"}} + {{if ne .Convert ""}} + o.{{.Name}} = {{.FieldType}}(u.Unmarshal{{.Encoder}}()) + {{else if .IsBasic}} + {{if ge .Max 1}} + o.{{.Name}} = u.Unmarshal{{.Encoder}}Max({{.Max}}) + {{else}} + o.{{.Name}} = u.Unmarshal{{.Encoder}}() + {{end}} + {{else}} + (&o.{{.Name}}).UnmarshalXDRFrom(u) + {{end}} +{{end}} + +{{define "unmarshalSlice"}} + _{{.Name}}Size := int(u.UnmarshalUint32()) + if _{{.Name}}Size < 0 { + return xdr.ElementSizeExceeded("{{.Name}}", _{{.Name}}Size, {{.Max}}) + } else if _{{.Name}}Size == 0 { + o.{{.Name}} = nil + } else { + {{if ge .Max 1}} + if _{{.Name}}Size > {{.Max}} { + return xdr.ElementSizeExceeded("{{.Name}}", _{{.Name}}Size, {{.Max}}) + } + {{end}} + if _{{.Name}}Size <= len(o.{{.Name}}) { + {{if eq .FieldType "string"}} + for i := _{{.Name}}Size; i < len(o.{{.Name}}); i++ { o.{{.Name}}[i] = "" } + {{end}} + {{if eq .FieldType "[]byte"}} + for i := _{{.Name}}Size; i < len(o.{{.Name}}); i++ { o.{{.Name}}[i] = nil } + {{end}} + o.{{.Name}} = o.{{.Name}}[:_{{.Name}}Size] + } else { + o.{{.Name}} = make([]{{.FieldType}}, _{{.Name}}Size) + } + for i := range o.{{.Name}} { + {{if ne .Convert ""}} + o.{{.Name}}[i] = {{.FieldType}}(u.Unmarshal{{.Encoder}}()) + {{else if .IsBasic}} + {{if ge .Submax 1}} + o.{{.Name}}[i] = u.Unmarshal{{.Encoder}}Max({{.Submax}}) + {{else}} + o.{{.Name}}[i] = u.Unmarshal{{.Encoder}}() + {{end}} + {{else}} + (&o.{{.Name}}[i]).UnmarshalXDRFrom(u) + {{end}} + } + } +{{end}} +` + +var ( + encodeTpl = template.Must(template.New("encoder").Parse(encoderData)) + headerTpl = template.Must(template.New("header").Parse(headerData)) +) var emptyTypeTpl = template.Must(template.New("encoder").Parse(` -func (o {{.TypeName}}) EncodeXDR(w io.Writer) (int, error) { - return 0, nil -}//+n +func (o {{.Name}}) XDRSize() int { + return 0 +} -func (o {{.TypeName}}) MarshalXDR() ([]byte, error) { +func (o {{.Name}}) MarshalXDR() ([]byte, error) { return nil, nil }//+n -func (o {{.TypeName}}) MustMarshalXDR() []byte { +func (o {{.Name}}) MustMarshalXDR() []byte { return nil }//+n -func (o {{.TypeName}}) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -}//+n - -func (o {{.TypeName}}) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -}//+n - -func (o *{{.TypeName}}) DecodeXDR(r io.Reader) error { +func (o {{.Name}}) MarshalXDRInto(m *xdr.Marshaller) error { return nil }//+n -func (o *{{.TypeName}}) UnmarshalXDR(bs []byte) error { +func (o *{{.Name}}) UnmarshalXDR(bs []byte) error { return nil }//+n -func (o *{{.TypeName}}) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() -}`)) +func (o *{{.Name}}) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil +}//+n +`)) var maxRe = regexp.MustCompile(`(?:\Wmax:)(\d+)(?:\s*,\s*(\d+))?`) @@ -286,7 +342,7 @@ func handleStruct(t *ast.StructType) []fieldInfo { f = fieldInfo{ Name: fn, IsBasic: true, - FieldType: tn, + FieldType: "[]" + tn, Encoder: enc.Encoder, Convert: enc.Type, Max: max1, @@ -329,17 +385,14 @@ func handleStruct(t *ast.StructType) []fieldInfo { } func generateCode(output io.Writer, s structInfo) { - name := s.Name - fs := s.Fields - var buf bytes.Buffer var err error - if len(fs) == 0 { + if len(s.Fields) == 0 { // This is an empty type. We can create a quite simple codec for it. - err = emptyTypeTpl.Execute(&buf, map[string]interface{}{"TypeName": name}) + err = emptyTypeTpl.Execute(&buf, s) } else { // Generate with the default template. - err = encodeTpl.Execute(&buf, map[string]interface{}{"TypeName": name, "Fields": fs}) + err = encodeTpl.Execute(&buf, s) } if err != nil { panic(err) @@ -347,12 +400,7 @@ func generateCode(output io.Writer, s structInfo) { bs := regexp.MustCompile(`(\s*\n)+`).ReplaceAll(buf.Bytes(), []byte("\n")) bs = bytes.Replace(bs, []byte("//+n"), []byte("\n"), -1) - - bs, err = format.Source(bs) - if err != nil { - panic(err) - } - fmt.Fprintln(output, string(bs)) + output.Write(bs) } func uncamelize(s string) string { @@ -384,46 +432,46 @@ func generateDiagram(output io.Writer, s structInfo) { tn := f.FieldType name := uncamelize(f.Name) + suffix := "" if f.IsSlice { fmt.Fprintf(output, "| %s |\n", center("Number of "+name, 61)) fmt.Fprintln(output, line) + suffix = " (n items)" + fmt.Fprintf(output, "/ %s /\n", center("", 61)) } switch tn { case "bool": fmt.Fprintf(output, "| %s |V|\n", center(name+" (V=0 or 1)", 59)) - fmt.Fprintln(output, line) case "int16", "uint16": - fmt.Fprintf(output, "| %s | %s |\n", center("0x0000", 29), center(name, 29)) - fmt.Fprintln(output, line) + fmt.Fprintf(output, "| %s | %s |\n", center("16 zero bits", 29), center(name, 29)) + case "int8", "uint8": + fmt.Fprintf(output, "| %s | %s |\n", center("24 zero bits", 45), center(name, 13)) case "int32", "uint32": - fmt.Fprintf(output, "| %s |\n", center(name, 61)) - fmt.Fprintln(output, line) + fmt.Fprintf(output, "| %s |\n", center(name+suffix, 61)) case "int64", "uint64": fmt.Fprintf(output, "| %-61s |\n", "") fmt.Fprintf(output, "+ %s +\n", center(name+" (64 bits)", 61)) fmt.Fprintf(output, "| %-61s |\n", "") - fmt.Fprintln(output, line) - case "string", "byte": // XXX We assume slice of byte! - fmt.Fprintf(output, "| %s |\n", center("Length of "+name, 61)) - fmt.Fprintln(output, line) + case "string", "[]byte": fmt.Fprintf(output, "/ %61s /\n", "") - fmt.Fprintf(output, "\\ %s \\\n", center(name+" (variable length)", 61)) + fmt.Fprintf(output, "\\ %s \\\n", center(name+" (length + padded data)", 61)) fmt.Fprintf(output, "/ %61s /\n", "") - fmt.Fprintln(output, line) default: if f.IsSlice { tn = "Zero or more " + tn + " Structures" - fmt.Fprintf(output, "/ %s /\n", center("", 61)) fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61)) - fmt.Fprintf(output, "/ %s /\n", center("", 61)) } else { tn = tn + " Structure" fmt.Fprintf(output, "/ %s /\n", center("", 61)) fmt.Fprintf(output, "\\ %s \\\n", center(tn, 61)) fmt.Fprintf(output, "/ %s /\n", center("", 61)) } - fmt.Fprintln(output, line) } + + if f.IsSlice { + fmt.Fprintf(output, "/ %s /\n", center("", 61)) + } + fmt.Fprintln(output, line) } fmt.Fprintln(output) fmt.Fprintln(output) @@ -448,9 +496,9 @@ func generateXdr(output io.Writer, s structInfo) { } switch tn { - case "int16", "int32": + case "int8", "int16", "int32": fmt.Fprintf(output, "\tint %s%s;\n", fn, suf) - case "uint16", "uint32": + case "uint8", "uint16", "uint32": fmt.Fprintf(output, "\tunsigned int %s%s;\n", fn, suf) case "int64": fmt.Fprintf(output, "\thyper %s%s;\n", fn, suf) @@ -458,7 +506,7 @@ func generateXdr(output io.Writer, s structInfo) { fmt.Fprintf(output, "\tunsigned hyper %s%s;\n", fn, suf) case "string": fmt.Fprintf(output, "\tstring %s<%s>;\n", fn, l) - case "byte": + case "[]byte": fmt.Fprintf(output, "\topaque %s<%s>;\n", fn, l) default: fmt.Fprintf(output, "\t%s %s%s;\n", tn, fn, suf) @@ -510,6 +558,22 @@ func main() { i := inspector(&structs) ast.Inspect(f, i) + buf := new(bytes.Buffer) + headerTpl.Execute(buf, map[string]string{"Package": f.Name.Name}) + for _, s := range structs { + fmt.Fprintf(buf, "\n/*\n\n") + generateDiagram(buf, s) + generateXdr(buf, s) + fmt.Fprintf(buf, "*/\n") + generateCode(buf, s) + } + + bs, err := format.Source(buf.Bytes()) + if err != nil { + log.Print(buf.String()) + log.Fatal(err) + } + var output io.Writer = os.Stdout if *outputFile != "" { fd, err := os.Create(*outputFile) @@ -518,13 +582,5 @@ func main() { } output = fd } - - headerTpl.Execute(output, map[string]string{"Package": f.Name.Name}) - for _, s := range structs { - fmt.Fprintf(output, "\n/*\n\n") - generateDiagram(output, s) - generateXdr(output, s) - fmt.Fprintf(output, "*/\n") - generateCode(output, s) - } + output.Write(bs) } diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/common.go b/Godeps/_workspace/src/github.com/calmh/xdr/common.go new file mode 100644 index 00000000..1100a61f --- /dev/null +++ b/Godeps/_workspace/src/github.com/calmh/xdr/common.go @@ -0,0 +1,59 @@ +// Copyright (C) 2014 Jakob Borg. 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 + +import ( + "fmt" + "reflect" +) + +var padBytes = []byte{0, 0, 0} + +// Pad returns the number of bytes that should be added to an item of length l +// bytes to conform to the XDR padding standard. This function is used by the +// generated marshalling code. +func Padding(l int) int { + d := l % 4 + if d == 0 { + return 0 + } + return 4 - d +} + +// ElementSizeExceeded returns an error describing the violated size +// constraint. This function is used by the generated marshalling code. +func ElementSizeExceeded(field string, size, limit int) error { + return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit) +} + +type XDRSizer interface { + XDRSize() int +} + +// SizeOfSlice returns the XDR encoded size of the given []T. Supported types +// for T are string, []byte and types implementing XDRSizer. SizeOfSlice +// panics if the parameter is not a slice or if T is not one of the supported +// types. This function is used by the generated marshalling code. +func SizeOfSlice(ss interface{}) int { + l := 0 + switch ss := ss.(type) { + case []string: + for _, s := range ss { + l += 4 + len(s) + Padding(len(s)) + } + + case [][]byte: + for _, s := range ss { + l += 4 + len(s) + Padding(len(s)) + } + + default: + v := reflect.ValueOf(ss) + for i := 0; i < v.Len(); i++ { + l += v.Index(i).Interface().(XDRSizer).XDRSize() + } + } + + return l +} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/debug.go b/Godeps/_workspace/src/github.com/calmh/xdr/debug.go deleted file mode 100644 index be3f092b..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/debug.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. 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 - -import ( - "log" - "os" -) - -var ( - debug = len(os.Getenv("XDRTRACE")) > 0 - dl = log.New(os.Stdout, "xdr: ", log.Lshortfile|log.Ltime|log.Lmicroseconds) -) - -const maxDebugBytes = 32 diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/doc.go b/Godeps/_workspace/src/github.com/calmh/xdr/doc.go index 41b59bc1..550d1d5f 100644 --- a/Godeps/_workspace/src/github.com/calmh/xdr/doc.go +++ b/Godeps/_workspace/src/github.com/calmh/xdr/doc.go @@ -1,5 +1,5 @@ // Copyright (C) 2014 Jakob Borg. 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 implements an XDR (RFC 4506) encoder/decoder. +// Package xdr implements an XDR (RFC 4506) marshaller/unmarshaller. package xdr diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/marshaller.go b/Godeps/_workspace/src/github.com/calmh/xdr/marshaller.go new file mode 100644 index 00000000..27aff824 --- /dev/null +++ b/Godeps/_workspace/src/github.com/calmh/xdr/marshaller.go @@ -0,0 +1,123 @@ +// Copyright (C) 2014 Jakob Borg. 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 + +import "io" + +// The Marshaller is a thin wrapper around a byte buffer. The buffer must be +// of sufficient size to hold the complete marshalled object, or an +// io.ErrShortBuffer error will result. The Marshal... methods don't +// individually return an error - the intention is that multiple fields are +// marshalled in rapid succession, followed by a check of the Error field on +// the Marshaller. +type Marshaller struct { + Data []byte + Error error + + offset int +} + +// MarshalRaw copies the raw bytes to the buffer, without a size prefix or +// padding. This is suitable for appending data already in XDR format from +// another source. +func (m *Marshaller) MarshalRaw(bs []byte) { + if m.Error != nil { + return + } + if len(m.Data) < m.offset+len(bs) { + m.Error = io.ErrShortBuffer + return + } + + m.offset += copy(m.Data[m.offset:], bs) +} + +// MarshalString appends the string to the buffer, with a size prefix and +// correct padding. +func (m *Marshaller) MarshalString(s string) { + if m.Error != nil { + return + } + if len(m.Data) < m.offset+4+len(s)+Padding(len(s)) { + m.Error = io.ErrShortBuffer + return + } + + m.MarshalUint32(uint32(len(s))) + m.offset += copy(m.Data[m.offset:], s) + m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(s))]) +} + +// MarshalString appends the bytes to the buffer, with a size prefix and +// correct padding. +func (m *Marshaller) MarshalBytes(bs []byte) { + if m.Error != nil { + return + } + if len(m.Data) < m.offset+4+len(bs)+Padding(len(bs)) { + m.Error = io.ErrShortBuffer + return + } + + m.MarshalUint32(uint32(len(bs))) + m.offset += copy(m.Data[m.offset:], bs) + m.offset += copy(m.Data[m.offset:], padBytes[:Padding(len(bs))]) +} + +// MarshalString appends the bool to the buffer, as an uint32. +func (m *Marshaller) MarshalBool(v bool) { + if v { + m.MarshalUint8(1) + } else { + m.MarshalUint8(0) + } +} + +// MarshalString appends the uint8 to the buffer, as an uint32. +func (m *Marshaller) MarshalUint8(v uint8) { + m.MarshalUint32(uint32(v)) +} + +// MarshalString appends the uint16 to the buffer, as an uint32. +func (m *Marshaller) MarshalUint16(v uint16) { + m.MarshalUint32(uint32(v)) +} + +// MarshalString appends the uint32 to the buffer. +func (m *Marshaller) MarshalUint32(v uint32) { + if m.Error != nil { + return + } + if len(m.Data) < m.offset+4 { + m.Error = io.ErrShortBuffer + return + } + + m.Data[m.offset+0] = byte(v >> 24) + m.Data[m.offset+1] = byte(v >> 16) + m.Data[m.offset+2] = byte(v >> 8) + m.Data[m.offset+3] = byte(v) + m.offset += 4 +} + +// MarshalString appends the uint64 to the buffer. +func (m *Marshaller) MarshalUint64(v uint64) { + if m.Error != nil { + return + } + if len(m.Data) < m.offset+8 { + m.Error = io.ErrShortBuffer + return + } + + m.Data[m.offset+0] = byte(v >> 56) + m.Data[m.offset+1] = byte(v >> 48) + m.Data[m.offset+2] = byte(v >> 40) + m.Data[m.offset+3] = byte(v >> 32) + m.Data[m.offset+4] = byte(v >> 24) + m.Data[m.offset+5] = byte(v >> 16) + m.Data[m.offset+6] = byte(v >> 8) + m.Data[m.offset+7] = byte(v) + m.offset += 8 +} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/pad_ipdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/pad_ipdr.go deleted file mode 100644 index 813a9b61..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/pad_ipdr.go +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code -// is governed by an MIT-style license that can be found in the LICENSE file. - -// +build ipdr - -package xdr - -func pad(l int) int { - return 0 -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/pad_xdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/pad_xdr.go deleted file mode 100644 index b1cac864..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/pad_xdr.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code -// is governed by an MIT-style license that can be found in the LICENSE file. - -// +build !ipdr - -package xdr - -func pad(l int) int { - d := l % 4 - if d == 0 { - return 0 - } - return 4 - d -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/reader.go b/Godeps/_workspace/src/github.com/calmh/xdr/reader.go deleted file mode 100644 index feb3cd31..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/reader.go +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). -// 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 - -import ( - "fmt" - "io" - "reflect" - "unsafe" -) - -type Reader struct { - r io.Reader - err error - b [8]byte -} - -func NewReader(r io.Reader) *Reader { - return &Reader{ - r: r, - } -} - -func (r *Reader) ReadRaw(bs []byte) (int, error) { - if r.err != nil { - return 0, r.err - } - - var n int - n, r.err = io.ReadFull(r.r, bs) - return n, r.err -} - -func (r *Reader) ReadString() string { - return r.ReadStringMax(0) -} - -func (r *Reader) ReadStringMax(max int) string { - buf := r.ReadBytesMaxInto(max, nil) - bh := (*reflect.SliceHeader)(unsafe.Pointer(&buf)) - sh := reflect.StringHeader{ - Data: bh.Data, - Len: bh.Len, - } - return *((*string)(unsafe.Pointer(&sh))) -} - -func (r *Reader) ReadBytes() []byte { - return r.ReadBytesInto(nil) -} - -func (r *Reader) ReadBytesMax(max int) []byte { - return r.ReadBytesMaxInto(max, nil) -} - -func (r *Reader) ReadBytesInto(dst []byte) []byte { - return r.ReadBytesMaxInto(0, dst) -} - -func (r *Reader) ReadBytesMaxInto(max int, dst []byte) []byte { - if r.err != nil { - return nil - } - - l := int(r.ReadUint32()) - if r.err != nil { - return nil - } - if l < 0 || max > 0 && l > max { - // l may be negative on 32 bit builds - r.err = ElementSizeExceeded("bytes field", l, max) - return nil - } - - if fullLen := l + pad(l); fullLen > len(dst) { - dst = make([]byte, fullLen) - } else { - dst = dst[:fullLen] - } - - var n int - n, r.err = io.ReadFull(r.r, dst) - if r.err != nil { - if debug { - dl.Printf("rd bytes (%d): %v", len(dst), r.err) - } - return nil - } - - if debug { - if n > maxDebugBytes { - dl.Printf("rd bytes (%d): %x...", len(dst), dst[:maxDebugBytes]) - } else { - dl.Printf("rd bytes (%d): %x", len(dst), dst) - } - } - return dst[:l] -} - -func (r *Reader) ReadBool() bool { - return r.ReadUint8() != 0 -} - -func (r *Reader) ReadUint32() uint32 { - if r.err != nil { - return 0 - } - - _, r.err = io.ReadFull(r.r, r.b[:4]) - if r.err != nil { - if debug { - dl.Printf("rd uint32: %v", r.err) - } - return 0 - } - - v := uint32(r.b[3]) | uint32(r.b[2])<<8 | uint32(r.b[1])<<16 | uint32(r.b[0])<<24 - - if debug { - dl.Printf("rd uint32=%d (0x%08x)", v, v) - } - return v -} - -func (r *Reader) ReadUint64() uint64 { - if r.err != nil { - return 0 - } - - _, r.err = io.ReadFull(r.r, r.b[:8]) - if r.err != nil { - if debug { - dl.Printf("rd uint64: %v", r.err) - } - return 0 - } - - v := uint64(r.b[7]) | uint64(r.b[6])<<8 | uint64(r.b[5])<<16 | uint64(r.b[4])<<24 | - uint64(r.b[3])<<32 | uint64(r.b[2])<<40 | uint64(r.b[1])<<48 | uint64(r.b[0])<<56 - - if debug { - dl.Printf("rd uint64=%d (0x%016x)", v, v) - } - return v -} - -type XDRError struct { - op string - err error -} - -func (e XDRError) Error() string { - return "xdr " + e.op + ": " + e.err.Error() -} - -func (e XDRError) IsEOF() bool { - return e.err == io.EOF -} - -func (r *Reader) Error() error { - if r.err == nil { - return nil - } - return XDRError{"read", r.err} -} - -func ElementSizeExceeded(field string, size, limit int) error { - return fmt.Errorf("%s exceeds size limit; %d > %d", field, size, limit) -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/reader_ipdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/reader_ipdr.go deleted file mode 100644 index 28e0b56a..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/reader_ipdr.go +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). -// All rights reserved. Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file. - -// +build ipdr - -package xdr - -import "io" - -func (r *Reader) ReadUint8() uint8 { - if r.err != nil { - return 0 - } - - _, r.err = io.ReadFull(r.r, r.b[:1]) - if r.err != nil { - if debug { - dl.Printf("rd uint8: %v", r.err) - } - return 0 - } - - if debug { - dl.Printf("rd uint8=%d (0x%02x)", r.b[0], r.b[0]) - } - return r.b[0] -} - -func (r *Reader) ReadUint16() uint16 { - if r.err != nil { - return 0 - } - - _, r.err = io.ReadFull(r.r, r.b[:2]) - if r.err != nil { - if debug { - dl.Printf("rd uint16: %v", r.err) - } - return 0 - } - - v := uint16(r.b[1]) | uint16(r.b[0])<<8 - - if debug { - dl.Printf("rd uint16=%d (0x%04x)", v, v) - } - return v -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/reader_xdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/reader_xdr.go deleted file mode 100644 index 4ac629a0..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/reader_xdr.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). -// All rights reserved. Use of this source code is governed by an MIT-style -// license that can be found in the LICENSE file. - -// +build !ipdr - -package xdr - -func (r *Reader) ReadUint8() uint8 { - return uint8(r.ReadUint32()) -} - -func (r *Reader) ReadUint16() uint16 { - return uint16(r.ReadUint32()) -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/unmarshal.go b/Godeps/_workspace/src/github.com/calmh/xdr/unmarshal.go new file mode 100644 index 00000000..3115d555 --- /dev/null +++ b/Godeps/_workspace/src/github.com/calmh/xdr/unmarshal.go @@ -0,0 +1,147 @@ +// Copyright (C) 2014 Jakob Borg and Contributors (see the CONTRIBUTORS file). +// 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 + +import ( + "io" + "reflect" + "unsafe" +) + +type Unmarshaller struct { + Error error + Data []byte +} + +func (u *Unmarshaller) UnmarshalRaw(l int) []byte { + if u.Error != nil { + return nil + } + if len(u.Data) < l { + u.Error = io.ErrUnexpectedEOF + return nil + } + + v := u.Data[:l] + u.Data = u.Data[l:] + + return v +} + +func (u *Unmarshaller) UnmarshalString() string { + return u.UnmarshalStringMax(0) +} + +func (u *Unmarshaller) UnmarshalStringMax(max int) string { + buf := u.UnmarshalBytesMax(max) + if len(buf) == 0 || u.Error != nil { + return "" + } + + var v string + p := (*reflect.StringHeader)(unsafe.Pointer(&v)) + p.Data = uintptr(unsafe.Pointer(&buf[0])) + p.Len = len(buf) + return v +} + +func (u *Unmarshaller) UnmarshalBytes() []byte { + return u.UnmarshalBytesMax(0) +} + +func (u *Unmarshaller) UnmarshalBytesMax(max int) []byte { + if u.Error != nil { + return nil + } + if len(u.Data) < 4 { + u.Error = io.ErrUnexpectedEOF + return nil + } + + l := int(u.Data[3]) | int(u.Data[2])<<8 | int(u.Data[1])<<16 | int(u.Data[0])<<24 + if l == 0 { + u.Data = u.Data[4:] + return nil + } + if l < 0 || max > 0 && l > max { + // l may be negative on 32 bit builds + u.Error = ElementSizeExceeded("bytes field", l, max) + return nil + } + if len(u.Data) < l+4 { + u.Error = io.ErrUnexpectedEOF + return nil + } + + v := u.Data[4 : 4+l] + u.Data = u.Data[4+l+Padding(l):] + + return v +} + +func (u *Unmarshaller) UnmarshalBool() bool { + return u.UnmarshalUint8() != 0 +} + +func (u *Unmarshaller) UnmarshalUint8() uint8 { + if u.Error != nil { + return 0 + } + if len(u.Data) < 4 { + u.Error = io.ErrUnexpectedEOF + return 0 + } + + v := uint8(u.Data[3]) + u.Data = u.Data[4:] + + return v +} + +func (u *Unmarshaller) UnmarshalUint16() uint16 { + if u.Error != nil { + return 0 + } + if len(u.Data) < 4 { + u.Error = io.ErrUnexpectedEOF + return 0 + } + + v := uint16(u.Data[3]) | uint16(u.Data[2])<<8 + u.Data = u.Data[4:] + + return v +} + +func (u *Unmarshaller) UnmarshalUint32() uint32 { + if u.Error != nil { + return 0 + } + if len(u.Data) < 4 { + u.Error = io.ErrUnexpectedEOF + return 0 + } + + v := uint32(u.Data[3]) | uint32(u.Data[2])<<8 | uint32(u.Data[1])<<16 | uint32(u.Data[0])<<24 + u.Data = u.Data[4:] + + return v +} + +func (u *Unmarshaller) UnmarshalUint64() uint64 { + if u.Error != nil { + return 0 + } + if len(u.Data) < 8 { + u.Error = io.ErrUnexpectedEOF + return 0 + } + + v := uint64(u.Data[7]) | uint64(u.Data[6])<<8 | uint64(u.Data[5])<<16 | uint64(u.Data[4])<<24 | + uint64(u.Data[3])<<32 | uint64(u.Data[2])<<40 | uint64(u.Data[1])<<48 | uint64(u.Data[0])<<56 + u.Data = u.Data[8:] + + return v +} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/writer.go b/Godeps/_workspace/src/github.com/calmh/xdr/writer.go deleted file mode 100644 index d1ec47bc..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/writer.go +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. 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 - -import ( - "io" - "reflect" - "unsafe" -) - -var padBytes = []byte{0, 0, 0} - -type Writer struct { - w io.Writer - tot int - err error - b [8]byte -} - -type AppendWriter []byte - -func (w *AppendWriter) Write(bs []byte) (int, error) { - *w = append(*w, bs...) - return len(bs), nil -} - -func NewWriter(w io.Writer) *Writer { - return &Writer{ - w: w, - } -} - -func (w *Writer) WriteRaw(bs []byte) (int, error) { - if w.err != nil { - return 0, w.err - } - - var n int - n, w.err = w.w.Write(bs) - return n, w.err -} - -func (w *Writer) WriteString(s string) (int, error) { - sh := *((*reflect.StringHeader)(unsafe.Pointer(&s))) - bh := reflect.SliceHeader{ - Data: sh.Data, - Len: sh.Len, - Cap: sh.Len, - } - return w.WriteBytes(*(*[]byte)(unsafe.Pointer(&bh))) -} - -func (w *Writer) WriteBytes(bs []byte) (int, error) { - if w.err != nil { - return 0, w.err - } - - w.WriteUint32(uint32(len(bs))) - if w.err != nil { - return 0, w.err - } - - if debug { - if len(bs) > maxDebugBytes { - dl.Printf("wr bytes (%d): %x...", len(bs), bs[:maxDebugBytes]) - } else { - dl.Printf("wr bytes (%d): %x", len(bs), bs) - } - } - - var l, n int - n, w.err = w.w.Write(bs) - l += n - - if p := pad(len(bs)); w.err == nil && p > 0 { - n, w.err = w.w.Write(padBytes[:p]) - l += n - } - - w.tot += l - return l, w.err -} - -func (w *Writer) WriteBool(v bool) (int, error) { - if v { - return w.WriteUint8(1) - } else { - return w.WriteUint8(0) - } -} - -func (w *Writer) WriteUint32(v uint32) (int, error) { - if w.err != nil { - return 0, w.err - } - - if debug { - dl.Printf("wr uint32=%d", v) - } - - w.b[0] = byte(v >> 24) - w.b[1] = byte(v >> 16) - w.b[2] = byte(v >> 8) - w.b[3] = byte(v) - - var l int - l, w.err = w.w.Write(w.b[:4]) - w.tot += l - return l, w.err -} - -func (w *Writer) WriteUint64(v uint64) (int, error) { - if w.err != nil { - return 0, w.err - } - - if debug { - dl.Printf("wr uint64=%d", v) - } - - w.b[0] = byte(v >> 56) - w.b[1] = byte(v >> 48) - w.b[2] = byte(v >> 40) - w.b[3] = byte(v >> 32) - w.b[4] = byte(v >> 24) - w.b[5] = byte(v >> 16) - w.b[6] = byte(v >> 8) - w.b[7] = byte(v) - - var l int - l, w.err = w.w.Write(w.b[:8]) - w.tot += l - return l, w.err -} - -func (w *Writer) Tot() int { - return w.tot -} - -func (w *Writer) Error() error { - if w.err == nil { - return nil - } - return XDRError{"write", w.err} -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/writer_ipdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/writer_ipdr.go deleted file mode 100644 index df803ae3..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/writer_ipdr.go +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code -// is governed by an MIT-style license that can be found in the LICENSE file. - -// +build ipdr - -package xdr - -func (w *Writer) WriteUint8(v uint8) (int, error) { - if w.err != nil { - return 0, w.err - } - - if debug { - dl.Printf("wr uint8=%d", v) - } - - w.b[0] = byte(v) - - var l int - l, w.err = w.w.Write(w.b[:1]) - w.tot += l - return l, w.err -} - -func (w *Writer) WriteUint16(v uint16) (int, error) { - if w.err != nil { - return 0, w.err - } - - if debug { - dl.Printf("wr uint8=%d", v) - } - - w.b[0] = byte(v >> 8) - w.b[1] = byte(v) - - var l int - l, w.err = w.w.Write(w.b[:2]) - w.tot += l - return l, w.err -} diff --git a/Godeps/_workspace/src/github.com/calmh/xdr/writer_xdr.go b/Godeps/_workspace/src/github.com/calmh/xdr/writer_xdr.go deleted file mode 100644 index 190fd549..00000000 --- a/Godeps/_workspace/src/github.com/calmh/xdr/writer_xdr.go +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright (C) 2014 Jakob Borg. All rights reserved. Use of this source code -// is governed by an MIT-style license that can be found in the LICENSE file. - -// +build !ipdr - -package xdr - -func (w *Writer) WriteUint8(v uint8) (int, error) { - return w.WriteUint32(uint32(v)) -} - -func (w *Writer) WriteUint16(v uint16) (int, error) { - return w.WriteUint32(uint32(v)) -} diff --git a/Godeps/_workspace/src/github.com/syndtr/goleveldb/LICENSE b/Godeps/_workspace/src/github.com/syndtr/goleveldb/LICENSE new file mode 100644 index 00000000..4a772d1a --- /dev/null +++ b/Godeps/_workspace/src/github.com/syndtr/goleveldb/LICENSE @@ -0,0 +1,24 @@ +Copyright 2012 Suryandaru Triandana +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/github.com/vitrun/qart/LICENSE b/Godeps/_workspace/src/github.com/vitrun/qart/LICENSE new file mode 100644 index 00000000..ad410e11 --- /dev/null +++ b/Godeps/_workspace/src/github.com/vitrun/qart/LICENSE @@ -0,0 +1,201 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/Godeps/_workspace/src/golang.org/x/crypto/LICENSE b/Godeps/_workspace/src/golang.org/x/crypto/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/golang.org/x/crypto/PATENTS b/Godeps/_workspace/src/golang.org/x/crypto/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/crypto/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/golang.org/x/net/LICENSE b/Godeps/_workspace/src/golang.org/x/net/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/golang.org/x/net/PATENTS b/Godeps/_workspace/src/golang.org/x/net/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64.go b/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64.go new file mode 100644 index 00000000..ec8ce157 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64 + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go b/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go new file mode 100644 index 00000000..2341ae67 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/ipv6/zsys_linux_mips64le.go @@ -0,0 +1,156 @@ +// Created by cgo -godefs - DO NOT EDIT +// cgo -godefs defs_linux.go + +// +build linux,mips64le + +package ipv6 + +const ( + sysIPV6_ADDRFORM = 0x1 + sysIPV6_2292PKTINFO = 0x2 + sysIPV6_2292HOPOPTS = 0x3 + sysIPV6_2292DSTOPTS = 0x4 + sysIPV6_2292RTHDR = 0x5 + sysIPV6_2292PKTOPTIONS = 0x6 + sysIPV6_CHECKSUM = 0x7 + sysIPV6_2292HOPLIMIT = 0x8 + sysIPV6_NEXTHOP = 0x9 + sysIPV6_FLOWINFO = 0xb + + sysIPV6_UNICAST_HOPS = 0x10 + sysIPV6_MULTICAST_IF = 0x11 + sysIPV6_MULTICAST_HOPS = 0x12 + sysIPV6_MULTICAST_LOOP = 0x13 + sysIPV6_ADD_MEMBERSHIP = 0x14 + sysIPV6_DROP_MEMBERSHIP = 0x15 + sysMCAST_JOIN_GROUP = 0x2a + sysMCAST_LEAVE_GROUP = 0x2d + sysMCAST_JOIN_SOURCE_GROUP = 0x2e + sysMCAST_LEAVE_SOURCE_GROUP = 0x2f + sysMCAST_BLOCK_SOURCE = 0x2b + sysMCAST_UNBLOCK_SOURCE = 0x2c + sysMCAST_MSFILTER = 0x30 + sysIPV6_ROUTER_ALERT = 0x16 + sysIPV6_MTU_DISCOVER = 0x17 + sysIPV6_MTU = 0x18 + sysIPV6_RECVERR = 0x19 + sysIPV6_V6ONLY = 0x1a + sysIPV6_JOIN_ANYCAST = 0x1b + sysIPV6_LEAVE_ANYCAST = 0x1c + + sysIPV6_FLOWLABEL_MGR = 0x20 + sysIPV6_FLOWINFO_SEND = 0x21 + + sysIPV6_IPSEC_POLICY = 0x22 + sysIPV6_XFRM_POLICY = 0x23 + + sysIPV6_RECVPKTINFO = 0x31 + sysIPV6_PKTINFO = 0x32 + sysIPV6_RECVHOPLIMIT = 0x33 + sysIPV6_HOPLIMIT = 0x34 + sysIPV6_RECVHOPOPTS = 0x35 + sysIPV6_HOPOPTS = 0x36 + sysIPV6_RTHDRDSTOPTS = 0x37 + sysIPV6_RECVRTHDR = 0x38 + sysIPV6_RTHDR = 0x39 + sysIPV6_RECVDSTOPTS = 0x3a + sysIPV6_DSTOPTS = 0x3b + sysIPV6_RECVPATHMTU = 0x3c + sysIPV6_PATHMTU = 0x3d + sysIPV6_DONTFRAG = 0x3e + + sysIPV6_RECVTCLASS = 0x42 + sysIPV6_TCLASS = 0x43 + + sysIPV6_ADDR_PREFERENCES = 0x48 + + sysIPV6_PREFER_SRC_TMP = 0x1 + sysIPV6_PREFER_SRC_PUBLIC = 0x2 + sysIPV6_PREFER_SRC_PUBTMP_DEFAULT = 0x100 + sysIPV6_PREFER_SRC_COA = 0x4 + sysIPV6_PREFER_SRC_HOME = 0x400 + sysIPV6_PREFER_SRC_CGA = 0x8 + sysIPV6_PREFER_SRC_NONCGA = 0x800 + + sysIPV6_MINHOPCOUNT = 0x49 + + sysIPV6_ORIGDSTADDR = 0x4a + sysIPV6_RECVORIGDSTADDR = 0x4a + sysIPV6_TRANSPARENT = 0x4b + sysIPV6_UNICAST_IF = 0x4c + + sysICMPV6_FILTER = 0x1 + + sysICMPV6_FILTER_BLOCK = 0x1 + sysICMPV6_FILTER_PASS = 0x2 + sysICMPV6_FILTER_BLOCKOTHERS = 0x3 + sysICMPV6_FILTER_PASSONLY = 0x4 + + sysSizeofKernelSockaddrStorage = 0x80 + sysSizeofSockaddrInet6 = 0x1c + sysSizeofInet6Pktinfo = 0x14 + sysSizeofIPv6Mtuinfo = 0x20 + sysSizeofIPv6FlowlabelReq = 0x20 + + sysSizeofIPv6Mreq = 0x14 + sysSizeofGroupReq = 0x88 + sysSizeofGroupSourceReq = 0x108 + + sysSizeofICMPv6Filter = 0x20 +) + +type sysKernelSockaddrStorage struct { + Family uint16 + X__data [126]int8 +} + +type sysSockaddrInet6 struct { + Family uint16 + Port uint16 + Flowinfo uint32 + Addr [16]byte /* in6_addr */ + Scope_id uint32 +} + +type sysInet6Pktinfo struct { + Addr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysIPv6Mtuinfo struct { + Addr sysSockaddrInet6 + Mtu uint32 +} + +type sysIPv6FlowlabelReq struct { + Dst [16]byte /* in6_addr */ + Label uint32 + Action uint8 + Share uint8 + Flags uint16 + Expires uint16 + Linger uint16 + X__flr_pad uint32 +} + +type sysIPv6Mreq struct { + Multiaddr [16]byte /* in6_addr */ + Ifindex int32 +} + +type sysGroupReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage +} + +type sysGroupSourceReq struct { + Interface uint32 + Pad_cgo_0 [4]byte + Group sysKernelSockaddrStorage + Source sysKernelSockaddrStorage +} + +type sysICMPv6Filter struct { + Data [8]uint32 +} diff --git a/Godeps/_workspace/src/golang.org/x/text/LICENSE b/Godeps/_workspace/src/golang.org/x/text/LICENSE new file mode 100644 index 00000000..6a66aea5 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/text/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Godeps/_workspace/src/golang.org/x/text/PATENTS b/Godeps/_workspace/src/golang.org/x/text/PATENTS new file mode 100644 index 00000000..73309904 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/text/PATENTS @@ -0,0 +1,22 @@ +Additional IP Rights Grant (Patents) + +"This implementation" means the copyrightable works distributed by +Google as part of the Go project. + +Google hereby grants to You a perpetual, worldwide, non-exclusive, +no-charge, royalty-free, irrevocable (except as stated in this section) +patent license to make, have made, use, offer to sell, sell, import, +transfer and otherwise run, modify and propagate the contents of this +implementation of Go, where such license applies only to those patent +claims, both currently owned or controlled by Google and acquired in +the future, licensable by Google that are necessarily infringed by this +implementation of Go. This grant does not include claims that would be +infringed only as a consequence of further modification of this +implementation. If you or your agent or exclusive licensee institute or +order or agree to the institution of patent litigation against any +entity (including a cross-claim or counterclaim in a lawsuit) alleging +that this implementation of Go or any code incorporated within this +implementation of Go constitutes direct or contributory patent +infringement, or inducement of patent infringement, then any patent +rights granted to you under this License for this implementation of Go +shall terminate as of the date such litigation is filed. diff --git a/lib/db/leveldb_dbinstance.go b/lib/db/leveldb_dbinstance.go index f432d99e..a0a8ebbf 100644 --- a/lib/db/leveldb_dbinstance.go +++ b/lib/db/leveldb_dbinstance.go @@ -267,7 +267,11 @@ func (db *Instance) withHave(folder, device []byte, truncate bool, fn Iterator) defer dbi.Release() for dbi.Next() { - f, err := unmarshalTrunc(dbi.Value(), truncate) + // The iterator function may keep a reference to the unmarshalled + // struct, which in turn references the buffer it was unmarshalled + // from. dbi.Value() just returns an internal slice that it reuses, so + // we need to copy it. + f, err := unmarshalTrunc(append([]byte{}, dbi.Value()...), truncate) if err != nil { panic(err) } @@ -287,7 +291,11 @@ func (db *Instance) withAllFolderTruncated(folder []byte, fn func(device []byte, for dbi.Next() { device := db.deviceKeyDevice(dbi.Key()) var f FileInfoTruncated - err := f.UnmarshalXDR(dbi.Value()) + // The iterator function may keep a reference to the unmarshalled + // struct, which in turn references the buffer it was unmarshalled + // from. dbi.Value() just returns an internal slice that it reuses, so + // we need to copy it. + err := f.UnmarshalXDR(append([]byte{}, dbi.Value()...)) if err != nil { panic(err) } diff --git a/lib/db/leveldb_xdr.go b/lib/db/leveldb_xdr.go index fe9f9399..1348c3cb 100644 --- a/lib/db/leveldb_xdr.go +++ b/lib/db/leveldb_xdr.go @@ -5,9 +5,6 @@ package db import ( - "bytes" - "io" - "github.com/calmh/xdr" ) @@ -22,10 +19,8 @@ fileVersion Structure: \ Vector Structure \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of device | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ device (variable length) \ +\ device (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -37,13 +32,15 @@ struct fileVersion { */ -func (o fileVersion) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o fileVersion) XDRSize() int { + return o.version.XDRSize() + + 4 + len(o.device) + xdr.Padding(len(o.device)) } func (o fileVersion) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o fileVersion) MustMarshalXDR() []byte { @@ -54,37 +51,22 @@ func (o fileVersion) MustMarshalXDR() []byte { return bs } -func (o fileVersion) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o fileVersion) EncodeXDRInto(xw *xdr.Writer) (int, error) { - _, err := o.version.EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err +func (o fileVersion) MarshalXDRInto(m *xdr.Marshaller) error { + if err := o.version.MarshalXDRInto(m); err != nil { + return err } - xw.WriteBytes(o.device) - return xw.Tot(), xw.Error() -} - -func (o *fileVersion) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalBytes(o.device) + return m.Error } func (o *fileVersion) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *fileVersion) DecodeXDRFrom(xr *xdr.Reader) error { - (&o.version).DecodeXDRFrom(xr) - o.device = xr.ReadBytes() - return xr.Error() +func (o *fileVersion) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + (&o.version).UnmarshalXDRFrom(u) + o.device = u.UnmarshalBytes() + return u.Error } /* @@ -108,13 +90,14 @@ struct versionList { */ -func (o versionList) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o versionList) XDRSize() int { + return 4 + xdr.SizeOfSlice(o.versions) } func (o versionList) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o versionList) MustMarshalXDR() []byte { @@ -125,43 +108,35 @@ func (o versionList) MustMarshalXDR() []byte { return bs } -func (o versionList) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o versionList) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteUint32(uint32(len(o.versions))) +func (o versionList) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(uint32(len(o.versions))) for i := range o.versions { - _, err := o.versions[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.versions[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *versionList) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *versionList) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *versionList) DecodeXDRFrom(xr *xdr.Reader) error { - _versionsSize := int(xr.ReadUint32()) +func (o *versionList) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + _versionsSize := int(u.UnmarshalUint32()) if _versionsSize < 0 { return xdr.ElementSizeExceeded("versions", _versionsSize, 0) + } else if _versionsSize == 0 { + o.versions = nil + } else { + if _versionsSize <= len(o.versions) { + o.versions = o.versions[:_versionsSize] + } else { + o.versions = make([]fileVersion, _versionsSize) + } + for i := range o.versions { + (&o.versions[i]).UnmarshalXDRFrom(u) + } } - o.versions = make([]fileVersion, _versionsSize) - for i := range o.versions { - (&o.versions[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } diff --git a/lib/db/truncated.go b/lib/db/truncated.go index d61f1745..a1d31977 100644 --- a/lib/db/truncated.go +++ b/lib/db/truncated.go @@ -7,8 +7,6 @@ package db import ( - "bytes" - "github.com/calmh/xdr" "github.com/syncthing/syncthing/lib/protocol" ) @@ -18,32 +16,32 @@ type FileInfoTruncated struct { } func (o *FileInfoTruncated) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + return o.UnmarshalXDRFrom(&xdr.Unmarshaller{Data: bs}) } -func (o *FileInfoTruncated) DecodeXDRFrom(xr *xdr.Reader) error { - o.Name = xr.ReadStringMax(8192) - o.Flags = xr.ReadUint32() - o.Modified = int64(xr.ReadUint64()) - (&o.Version).DecodeXDRFrom(xr) - o.LocalVersion = int64(xr.ReadUint64()) - _BlocksSize := int(xr.ReadUint32()) +func (o *FileInfoTruncated) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Name = u.UnmarshalStringMax(8192) + o.Flags = u.UnmarshalUint32() + o.Modified = int64(u.UnmarshalUint64()) + (&o.Version).UnmarshalXDRFrom(u) + o.LocalVersion = int64(u.UnmarshalUint64()) + _BlocksSize := int(u.UnmarshalUint32()) if _BlocksSize < 0 { return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) - } - if _BlocksSize > 1000000 { - return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) + } else if _BlocksSize == 0 { + o.Blocks = nil + } else { + if _BlocksSize > 1000000 { + return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) + } + for i := 0; i < _BlocksSize; i++ { + size := int64(u.UnmarshalUint32()) + o.CachedSize += size + u.UnmarshalBytes() + } } - buf := make([]byte, 64) - for i := 0; i < _BlocksSize; i++ { - size := xr.ReadUint32() - o.CachedSize += int64(size) - xr.ReadBytesMaxInto(64, buf) - } - return xr.Error() + return u.Error } func BlocksToSize(num int) int64 { diff --git a/lib/discover/localpackets_xdr.go b/lib/discover/localpackets_xdr.go index dde5a3d5..d353a137 100644 --- a/lib/discover/localpackets_xdr.go +++ b/lib/discover/localpackets_xdr.go @@ -5,9 +5,6 @@ package discover import ( - "bytes" - "io" - "github.com/calmh/xdr" ) @@ -40,13 +37,16 @@ struct Announce { */ -func (o Announce) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Announce) XDRSize() int { + return 4 + + o.This.XDRSize() + + 4 + xdr.SizeOfSlice(o.Extra) } func (o Announce) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Announce) MustMarshalXDR() []byte { @@ -57,58 +57,49 @@ func (o Announce) MustMarshalXDR() []byte { return bs } -func (o Announce) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Announce) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteUint32(o.Magic) - _, err := o.This.EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err +func (o Announce) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(o.Magic) + if err := o.This.MarshalXDRInto(m); err != nil { + return err } if l := len(o.Extra); l > 16 { - return xw.Tot(), xdr.ElementSizeExceeded("Extra", l, 16) + return xdr.ElementSizeExceeded("Extra", l, 16) } - xw.WriteUint32(uint32(len(o.Extra))) + m.MarshalUint32(uint32(len(o.Extra))) for i := range o.Extra { - _, err := o.Extra[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Extra[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *Announce) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *Announce) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Announce) DecodeXDRFrom(xr *xdr.Reader) error { - o.Magic = xr.ReadUint32() - (&o.This).DecodeXDRFrom(xr) - _ExtraSize := int(xr.ReadUint32()) +func (o *Announce) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Magic = u.UnmarshalUint32() + (&o.This).UnmarshalXDRFrom(u) + _ExtraSize := int(u.UnmarshalUint32()) if _ExtraSize < 0 { return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16) + } else if _ExtraSize == 0 { + o.Extra = nil + } else { + if _ExtraSize > 16 { + return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16) + } + if _ExtraSize <= len(o.Extra) { + o.Extra = o.Extra[:_ExtraSize] + } else { + o.Extra = make([]Device, _ExtraSize) + } + for i := range o.Extra { + (&o.Extra[i]).UnmarshalXDRFrom(u) + } } - if _ExtraSize > 16 { - return xdr.ElementSizeExceeded("Extra", _ExtraSize, 16) - } - o.Extra = make([]Device, _ExtraSize) - for i := range o.Extra { - (&o.Extra[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -118,10 +109,8 @@ Device Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of ID | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ ID (variable length) \ +\ ID (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Addresses | @@ -146,13 +135,16 @@ struct Device { */ -func (o Device) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Device) XDRSize() int { + return 4 + len(o.ID) + xdr.Padding(len(o.ID)) + + 4 + xdr.SizeOfSlice(o.Addresses) + + 4 + xdr.SizeOfSlice(o.Relays) } func (o Device) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Device) MustMarshalXDR() []byte { @@ -163,77 +155,75 @@ func (o Device) MustMarshalXDR() []byte { return bs } -func (o Device) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Device) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.ID); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) + return xdr.ElementSizeExceeded("ID", l, 32) } - xw.WriteBytes(o.ID) + m.MarshalBytes(o.ID) if l := len(o.Addresses); l > 16 { - return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 16) + return xdr.ElementSizeExceeded("Addresses", l, 16) } - xw.WriteUint32(uint32(len(o.Addresses))) + m.MarshalUint32(uint32(len(o.Addresses))) for i := range o.Addresses { - _, err := o.Addresses[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Addresses[i].MarshalXDRInto(m); err != nil { + return err } } if l := len(o.Relays); l > 16 { - return xw.Tot(), xdr.ElementSizeExceeded("Relays", l, 16) + return xdr.ElementSizeExceeded("Relays", l, 16) } - xw.WriteUint32(uint32(len(o.Relays))) + m.MarshalUint32(uint32(len(o.Relays))) for i := range o.Relays { - _, err := o.Relays[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Relays[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *Device) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *Device) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { - o.ID = xr.ReadBytesMax(32) - _AddressesSize := int(xr.ReadUint32()) +func (o *Device) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.ID = u.UnmarshalBytesMax(32) + _AddressesSize := int(u.UnmarshalUint32()) if _AddressesSize < 0 { return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) + } else if _AddressesSize == 0 { + o.Addresses = nil + } else { + if _AddressesSize > 16 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) + } + if _AddressesSize <= len(o.Addresses) { + o.Addresses = o.Addresses[:_AddressesSize] + } else { + o.Addresses = make([]Address, _AddressesSize) + } + for i := range o.Addresses { + (&o.Addresses[i]).UnmarshalXDRFrom(u) + } } - if _AddressesSize > 16 { - return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 16) - } - o.Addresses = make([]Address, _AddressesSize) - for i := range o.Addresses { - (&o.Addresses[i]).DecodeXDRFrom(xr) - } - _RelaysSize := int(xr.ReadUint32()) + _RelaysSize := int(u.UnmarshalUint32()) if _RelaysSize < 0 { return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) + } else if _RelaysSize == 0 { + o.Relays = nil + } else { + if _RelaysSize > 16 { + return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) + } + if _RelaysSize <= len(o.Relays) { + o.Relays = o.Relays[:_RelaysSize] + } else { + o.Relays = make([]Relay, _RelaysSize) + } + for i := range o.Relays { + (&o.Relays[i]).UnmarshalXDRFrom(u) + } } - if _RelaysSize > 16 { - return xdr.ElementSizeExceeded("Relays", _RelaysSize, 16) - } - o.Relays = make([]Relay, _RelaysSize) - for i := range o.Relays { - (&o.Relays[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -243,10 +233,8 @@ Address Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of URL | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ URL (variable length) \ +\ URL (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -257,13 +245,14 @@ struct Address { */ -func (o Address) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Address) XDRSize() int { + return 4 + len(o.URL) + xdr.Padding(len(o.URL)) } func (o Address) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Address) MustMarshalXDR() []byte { @@ -274,35 +263,21 @@ func (o Address) MustMarshalXDR() []byte { return bs } -func (o Address) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Address) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Address) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.URL); l > 2083 { - return xw.Tot(), xdr.ElementSizeExceeded("URL", l, 2083) + return xdr.ElementSizeExceeded("URL", l, 2083) } - xw.WriteString(o.URL) - return xw.Tot(), xw.Error() -} - -func (o *Address) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalString(o.URL) + return m.Error } func (o *Address) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Address) DecodeXDRFrom(xr *xdr.Reader) error { - o.URL = xr.ReadStringMax(2083) - return xr.Error() +func (o *Address) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.URL = u.UnmarshalStringMax(2083) + return u.Error } /* @@ -312,10 +287,8 @@ Relay Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of URL | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ URL (variable length) \ +\ URL (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Latency | @@ -329,13 +302,14 @@ struct Relay { */ -func (o Relay) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Relay) XDRSize() int { + return 4 + len(o.URL) + xdr.Padding(len(o.URL)) + 4 } func (o Relay) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Relay) MustMarshalXDR() []byte { @@ -346,35 +320,21 @@ func (o Relay) MustMarshalXDR() []byte { return bs } -func (o Relay) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Relay) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Relay) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.URL); l > 2083 { - return xw.Tot(), xdr.ElementSizeExceeded("URL", l, 2083) + return xdr.ElementSizeExceeded("URL", l, 2083) } - xw.WriteString(o.URL) - xw.WriteUint32(uint32(o.Latency)) - return xw.Tot(), xw.Error() -} - -func (o *Relay) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalString(o.URL) + m.MarshalUint32(uint32(o.Latency)) + return m.Error } func (o *Relay) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Relay) DecodeXDRFrom(xr *xdr.Reader) error { - o.URL = xr.ReadStringMax(2083) - o.Latency = int32(xr.ReadUint32()) - return xr.Error() +func (o *Relay) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.URL = u.UnmarshalStringMax(2083) + o.Latency = int32(u.UnmarshalUint32()) + return u.Error } diff --git a/lib/protocol/header.go b/lib/protocol/header.go index 846ee48c..184d165d 100644 --- a/lib/protocol/header.go +++ b/lib/protocol/header.go @@ -11,15 +11,16 @@ type header struct { compression bool } -func (h header) encodeXDR(xw *xdr.Writer) (int, error) { - u := encodeHeader(h) - return xw.WriteUint32(u) +func (h header) MarshalXDRInto(m *xdr.Marshaller) error { + v := encodeHeader(h) + m.MarshalUint32(v) + return m.Error } -func (h *header) decodeXDR(xr *xdr.Reader) error { - u := xr.ReadUint32() - *h = decodeHeader(u) - return xr.Error() +func (h *header) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + v := u.UnmarshalUint32() + *h = decodeHeader(v) + return u.Error } func encodeHeader(h header) uint32 { diff --git a/lib/protocol/message_xdr.go b/lib/protocol/message_xdr.go index e2ea7ca6..4b4aff73 100644 --- a/lib/protocol/message_xdr.go +++ b/lib/protocol/message_xdr.go @@ -5,9 +5,6 @@ package protocol import ( - "bytes" - "io" - "github.com/calmh/xdr" ) @@ -18,10 +15,8 @@ IndexMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Folder | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Folder (variable length) \ +\ Folder (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Files | @@ -49,13 +44,16 @@ struct IndexMessage { */ -func (o IndexMessage) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o IndexMessage) XDRSize() int { + return 4 + len(o.Folder) + xdr.Padding(len(o.Folder)) + + 4 + xdr.SizeOfSlice(o.Files) + 4 + + 4 + xdr.SizeOfSlice(o.Options) } func (o IndexMessage) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o IndexMessage) MustMarshalXDR() []byte { @@ -66,79 +64,77 @@ func (o IndexMessage) MustMarshalXDR() []byte { return bs } -func (o IndexMessage) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o IndexMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o IndexMessage) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Folder); l > 256 { - return xw.Tot(), xdr.ElementSizeExceeded("Folder", l, 256) + return xdr.ElementSizeExceeded("Folder", l, 256) } - xw.WriteString(o.Folder) + m.MarshalString(o.Folder) if l := len(o.Files); l > 1000000 { - return xw.Tot(), xdr.ElementSizeExceeded("Files", l, 1000000) + return xdr.ElementSizeExceeded("Files", l, 1000000) } - xw.WriteUint32(uint32(len(o.Files))) + m.MarshalUint32(uint32(len(o.Files))) for i := range o.Files { - _, err := o.Files[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Files[i].MarshalXDRInto(m); err != nil { + return err } } - xw.WriteUint32(o.Flags) + m.MarshalUint32(o.Flags) if l := len(o.Options); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Options", l, 64) + return xdr.ElementSizeExceeded("Options", l, 64) } - xw.WriteUint32(uint32(len(o.Options))) + m.MarshalUint32(uint32(len(o.Options))) for i := range o.Options { - _, err := o.Options[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Options[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *IndexMessage) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *IndexMessage) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *IndexMessage) DecodeXDRFrom(xr *xdr.Reader) error { - o.Folder = xr.ReadStringMax(256) - _FilesSize := int(xr.ReadUint32()) +func (o *IndexMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Folder = u.UnmarshalStringMax(256) + _FilesSize := int(u.UnmarshalUint32()) if _FilesSize < 0 { return xdr.ElementSizeExceeded("Files", _FilesSize, 1000000) + } else if _FilesSize == 0 { + o.Files = nil + } else { + if _FilesSize > 1000000 { + return xdr.ElementSizeExceeded("Files", _FilesSize, 1000000) + } + if _FilesSize <= len(o.Files) { + o.Files = o.Files[:_FilesSize] + } else { + o.Files = make([]FileInfo, _FilesSize) + } + for i := range o.Files { + (&o.Files[i]).UnmarshalXDRFrom(u) + } } - if _FilesSize > 1000000 { - return xdr.ElementSizeExceeded("Files", _FilesSize, 1000000) - } - o.Files = make([]FileInfo, _FilesSize) - for i := range o.Files { - (&o.Files[i]).DecodeXDRFrom(xr) - } - o.Flags = xr.ReadUint32() - _OptionsSize := int(xr.ReadUint32()) + o.Flags = u.UnmarshalUint32() + _OptionsSize := int(u.UnmarshalUint32()) if _OptionsSize < 0 { return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } else if _OptionsSize == 0 { + o.Options = nil + } else { + if _OptionsSize > 64 { + return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } + if _OptionsSize <= len(o.Options) { + o.Options = o.Options[:_OptionsSize] + } else { + o.Options = make([]Option, _OptionsSize) + } + for i := range o.Options { + (&o.Options[i]).UnmarshalXDRFrom(u) + } } - if _OptionsSize > 64 { - return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) - } - o.Options = make([]Option, _OptionsSize) - for i := range o.Options { - (&o.Options[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -148,10 +144,8 @@ FileInfo Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Name (variable length) \ +\ Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flags | @@ -187,13 +181,16 @@ struct FileInfo { */ -func (o FileInfo) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o FileInfo) XDRSize() int { + return 4 + len(o.Name) + xdr.Padding(len(o.Name)) + 4 + 8 + + o.Version.XDRSize() + 8 + + 4 + xdr.SizeOfSlice(o.Blocks) } func (o FileInfo) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o FileInfo) MustMarshalXDR() []byte { @@ -204,67 +201,58 @@ func (o FileInfo) MustMarshalXDR() []byte { return bs } -func (o FileInfo) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o FileInfo) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o FileInfo) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Name); l > 8192 { - return xw.Tot(), xdr.ElementSizeExceeded("Name", l, 8192) + return xdr.ElementSizeExceeded("Name", l, 8192) } - xw.WriteString(o.Name) - xw.WriteUint32(o.Flags) - xw.WriteUint64(uint64(o.Modified)) - _, err := o.Version.EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + m.MarshalString(o.Name) + m.MarshalUint32(o.Flags) + m.MarshalUint64(uint64(o.Modified)) + if err := o.Version.MarshalXDRInto(m); err != nil { + return err } - xw.WriteUint64(uint64(o.LocalVersion)) + m.MarshalUint64(uint64(o.LocalVersion)) if l := len(o.Blocks); l > 1000000 { - return xw.Tot(), xdr.ElementSizeExceeded("Blocks", l, 1000000) + return xdr.ElementSizeExceeded("Blocks", l, 1000000) } - xw.WriteUint32(uint32(len(o.Blocks))) + m.MarshalUint32(uint32(len(o.Blocks))) for i := range o.Blocks { - _, err := o.Blocks[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Blocks[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *FileInfo) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *FileInfo) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *FileInfo) DecodeXDRFrom(xr *xdr.Reader) error { - o.Name = xr.ReadStringMax(8192) - o.Flags = xr.ReadUint32() - o.Modified = int64(xr.ReadUint64()) - (&o.Version).DecodeXDRFrom(xr) - o.LocalVersion = int64(xr.ReadUint64()) - _BlocksSize := int(xr.ReadUint32()) +func (o *FileInfo) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Name = u.UnmarshalStringMax(8192) + o.Flags = u.UnmarshalUint32() + o.Modified = int64(u.UnmarshalUint64()) + (&o.Version).UnmarshalXDRFrom(u) + o.LocalVersion = int64(u.UnmarshalUint64()) + _BlocksSize := int(u.UnmarshalUint32()) if _BlocksSize < 0 { return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) + } else if _BlocksSize == 0 { + o.Blocks = nil + } else { + if _BlocksSize > 1000000 { + return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) + } + if _BlocksSize <= len(o.Blocks) { + o.Blocks = o.Blocks[:_BlocksSize] + } else { + o.Blocks = make([]BlockInfo, _BlocksSize) + } + for i := range o.Blocks { + (&o.Blocks[i]).UnmarshalXDRFrom(u) + } } - if _BlocksSize > 1000000 { - return xdr.ElementSizeExceeded("Blocks", _BlocksSize, 1000000) - } - o.Blocks = make([]BlockInfo, _BlocksSize) - for i := range o.Blocks { - (&o.Blocks[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -276,10 +264,8 @@ BlockInfo Structure: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Hash | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Hash (variable length) \ +\ Hash (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -291,13 +277,15 @@ struct BlockInfo { */ -func (o BlockInfo) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o BlockInfo) XDRSize() int { + return 4 + + 4 + len(o.Hash) + xdr.Padding(len(o.Hash)) } func (o BlockInfo) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o BlockInfo) MustMarshalXDR() []byte { @@ -308,37 +296,23 @@ func (o BlockInfo) MustMarshalXDR() []byte { return bs } -func (o BlockInfo) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o BlockInfo) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteUint32(uint32(o.Size)) +func (o BlockInfo) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(uint32(o.Size)) if l := len(o.Hash); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Hash", l, 64) + return xdr.ElementSizeExceeded("Hash", l, 64) } - xw.WriteBytes(o.Hash) - return xw.Tot(), xw.Error() -} - -func (o *BlockInfo) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalBytes(o.Hash) + return m.Error } func (o *BlockInfo) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *BlockInfo) DecodeXDRFrom(xr *xdr.Reader) error { - o.Size = int32(xr.ReadUint32()) - o.Hash = xr.ReadBytesMax(64) - return xr.Error() +func (o *BlockInfo) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Size = int32(u.UnmarshalUint32()) + o.Hash = u.UnmarshalBytesMax(64) + return u.Error } /* @@ -348,16 +322,12 @@ RequestMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Folder | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Folder (variable length) \ +\ Folder (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Name (variable length) \ +\ Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | @@ -366,10 +336,8 @@ RequestMessage Structure: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Size | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Hash | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Hash (variable length) \ +\ Hash (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Flags | @@ -394,13 +362,17 @@ struct RequestMessage { */ -func (o RequestMessage) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o RequestMessage) XDRSize() int { + return 4 + len(o.Folder) + xdr.Padding(len(o.Folder)) + + 4 + len(o.Name) + xdr.Padding(len(o.Name)) + 8 + 4 + + 4 + len(o.Hash) + xdr.Padding(len(o.Hash)) + 4 + + 4 + xdr.SizeOfSlice(o.Options) } func (o RequestMessage) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o RequestMessage) MustMarshalXDR() []byte { @@ -411,72 +383,64 @@ func (o RequestMessage) MustMarshalXDR() []byte { return bs } -func (o RequestMessage) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o RequestMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o RequestMessage) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Folder); l > 256 { - return xw.Tot(), xdr.ElementSizeExceeded("Folder", l, 256) + return xdr.ElementSizeExceeded("Folder", l, 256) } - xw.WriteString(o.Folder) + m.MarshalString(o.Folder) if l := len(o.Name); l > 8192 { - return xw.Tot(), xdr.ElementSizeExceeded("Name", l, 8192) + return xdr.ElementSizeExceeded("Name", l, 8192) } - xw.WriteString(o.Name) - xw.WriteUint64(uint64(o.Offset)) - xw.WriteUint32(uint32(o.Size)) + m.MarshalString(o.Name) + m.MarshalUint64(uint64(o.Offset)) + m.MarshalUint32(uint32(o.Size)) if l := len(o.Hash); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Hash", l, 64) + return xdr.ElementSizeExceeded("Hash", l, 64) } - xw.WriteBytes(o.Hash) - xw.WriteUint32(o.Flags) + m.MarshalBytes(o.Hash) + m.MarshalUint32(o.Flags) if l := len(o.Options); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Options", l, 64) + return xdr.ElementSizeExceeded("Options", l, 64) } - xw.WriteUint32(uint32(len(o.Options))) + m.MarshalUint32(uint32(len(o.Options))) for i := range o.Options { - _, err := o.Options[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Options[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *RequestMessage) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *RequestMessage) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *RequestMessage) DecodeXDRFrom(xr *xdr.Reader) error { - o.Folder = xr.ReadStringMax(256) - o.Name = xr.ReadStringMax(8192) - o.Offset = int64(xr.ReadUint64()) - o.Size = int32(xr.ReadUint32()) - o.Hash = xr.ReadBytesMax(64) - o.Flags = xr.ReadUint32() - _OptionsSize := int(xr.ReadUint32()) +func (o *RequestMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Folder = u.UnmarshalStringMax(256) + o.Name = u.UnmarshalStringMax(8192) + o.Offset = int64(u.UnmarshalUint64()) + o.Size = int32(u.UnmarshalUint32()) + o.Hash = u.UnmarshalBytesMax(64) + o.Flags = u.UnmarshalUint32() + _OptionsSize := int(u.UnmarshalUint32()) if _OptionsSize < 0 { return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } else if _OptionsSize == 0 { + o.Options = nil + } else { + if _OptionsSize > 64 { + return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } + if _OptionsSize <= len(o.Options) { + o.Options = o.Options[:_OptionsSize] + } else { + o.Options = make([]Option, _OptionsSize) + } + for i := range o.Options { + (&o.Options[i]).UnmarshalXDRFrom(u) + } } - if _OptionsSize > 64 { - return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) - } - o.Options = make([]Option, _OptionsSize) - for i := range o.Options { - (&o.Options[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -486,10 +450,8 @@ ResponseMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Data | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Data (variable length) \ +\ Data (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Code | @@ -503,13 +465,14 @@ struct ResponseMessage { */ -func (o ResponseMessage) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o ResponseMessage) XDRSize() int { + return 4 + len(o.Data) + xdr.Padding(len(o.Data)) + 4 } func (o ResponseMessage) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o ResponseMessage) MustMarshalXDR() []byte { @@ -520,34 +483,20 @@ func (o ResponseMessage) MustMarshalXDR() []byte { return bs } -func (o ResponseMessage) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o ResponseMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteBytes(o.Data) - xw.WriteUint32(uint32(o.Code)) - return xw.Tot(), xw.Error() -} - -func (o *ResponseMessage) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) +func (o ResponseMessage) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalBytes(o.Data) + m.MarshalUint32(uint32(o.Code)) + return m.Error } func (o *ResponseMessage) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *ResponseMessage) DecodeXDRFrom(xr *xdr.Reader) error { - o.Data = xr.ReadBytes() - o.Code = int32(xr.ReadUint32()) - return xr.Error() +func (o *ResponseMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Data = u.UnmarshalBytes() + o.Code = int32(u.UnmarshalUint32()) + return u.Error } /* @@ -557,22 +506,16 @@ ClusterConfigMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Device Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Device Name (variable length) \ +\ Device Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Client Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Client Name (variable length) \ +\ Client Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Client Version | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Client Version (variable length) \ +\ Client Version (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Folders | @@ -599,13 +542,18 @@ struct ClusterConfigMessage { */ -func (o ClusterConfigMessage) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o ClusterConfigMessage) XDRSize() int { + return 4 + len(o.DeviceName) + xdr.Padding(len(o.DeviceName)) + + 4 + len(o.ClientName) + xdr.Padding(len(o.ClientName)) + + 4 + len(o.ClientVersion) + xdr.Padding(len(o.ClientVersion)) + + 4 + xdr.SizeOfSlice(o.Folders) + + 4 + xdr.SizeOfSlice(o.Options) } func (o ClusterConfigMessage) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o ClusterConfigMessage) MustMarshalXDR() []byte { @@ -616,87 +564,85 @@ func (o ClusterConfigMessage) MustMarshalXDR() []byte { return bs } -func (o ClusterConfigMessage) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o ClusterConfigMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o ClusterConfigMessage) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.DeviceName); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("DeviceName", l, 64) + return xdr.ElementSizeExceeded("DeviceName", l, 64) } - xw.WriteString(o.DeviceName) + m.MarshalString(o.DeviceName) if l := len(o.ClientName); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("ClientName", l, 64) + return xdr.ElementSizeExceeded("ClientName", l, 64) } - xw.WriteString(o.ClientName) + m.MarshalString(o.ClientName) if l := len(o.ClientVersion); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("ClientVersion", l, 64) + return xdr.ElementSizeExceeded("ClientVersion", l, 64) } - xw.WriteString(o.ClientVersion) + m.MarshalString(o.ClientVersion) if l := len(o.Folders); l > 1000000 { - return xw.Tot(), xdr.ElementSizeExceeded("Folders", l, 1000000) + return xdr.ElementSizeExceeded("Folders", l, 1000000) } - xw.WriteUint32(uint32(len(o.Folders))) + m.MarshalUint32(uint32(len(o.Folders))) for i := range o.Folders { - _, err := o.Folders[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Folders[i].MarshalXDRInto(m); err != nil { + return err } } if l := len(o.Options); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Options", l, 64) + return xdr.ElementSizeExceeded("Options", l, 64) } - xw.WriteUint32(uint32(len(o.Options))) + m.MarshalUint32(uint32(len(o.Options))) for i := range o.Options { - _, err := o.Options[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Options[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *ClusterConfigMessage) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *ClusterConfigMessage) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *ClusterConfigMessage) DecodeXDRFrom(xr *xdr.Reader) error { - o.DeviceName = xr.ReadStringMax(64) - o.ClientName = xr.ReadStringMax(64) - o.ClientVersion = xr.ReadStringMax(64) - _FoldersSize := int(xr.ReadUint32()) +func (o *ClusterConfigMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.DeviceName = u.UnmarshalStringMax(64) + o.ClientName = u.UnmarshalStringMax(64) + o.ClientVersion = u.UnmarshalStringMax(64) + _FoldersSize := int(u.UnmarshalUint32()) if _FoldersSize < 0 { return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000) + } else if _FoldersSize == 0 { + o.Folders = nil + } else { + if _FoldersSize > 1000000 { + return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000) + } + if _FoldersSize <= len(o.Folders) { + o.Folders = o.Folders[:_FoldersSize] + } else { + o.Folders = make([]Folder, _FoldersSize) + } + for i := range o.Folders { + (&o.Folders[i]).UnmarshalXDRFrom(u) + } } - if _FoldersSize > 1000000 { - return xdr.ElementSizeExceeded("Folders", _FoldersSize, 1000000) - } - o.Folders = make([]Folder, _FoldersSize) - for i := range o.Folders { - (&o.Folders[i]).DecodeXDRFrom(xr) - } - _OptionsSize := int(xr.ReadUint32()) + _OptionsSize := int(u.UnmarshalUint32()) if _OptionsSize < 0 { return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } else if _OptionsSize == 0 { + o.Options = nil + } else { + if _OptionsSize > 64 { + return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } + if _OptionsSize <= len(o.Options) { + o.Options = o.Options[:_OptionsSize] + } else { + o.Options = make([]Option, _OptionsSize) + } + for i := range o.Options { + (&o.Options[i]).UnmarshalXDRFrom(u) + } } - if _OptionsSize > 64 { - return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) - } - o.Options = make([]Option, _OptionsSize) - for i := range o.Options { - (&o.Options[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -706,10 +652,8 @@ Folder Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of ID | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ ID (variable length) \ +\ ID (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Devices | @@ -737,13 +681,16 @@ struct Folder { */ -func (o Folder) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Folder) XDRSize() int { + return 4 + len(o.ID) + xdr.Padding(len(o.ID)) + + 4 + xdr.SizeOfSlice(o.Devices) + 4 + + 4 + xdr.SizeOfSlice(o.Options) } func (o Folder) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Folder) MustMarshalXDR() []byte { @@ -754,79 +701,77 @@ func (o Folder) MustMarshalXDR() []byte { return bs } -func (o Folder) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Folder) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Folder) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.ID); l > 256 { - return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 256) + return xdr.ElementSizeExceeded("ID", l, 256) } - xw.WriteString(o.ID) + m.MarshalString(o.ID) if l := len(o.Devices); l > 1000000 { - return xw.Tot(), xdr.ElementSizeExceeded("Devices", l, 1000000) + return xdr.ElementSizeExceeded("Devices", l, 1000000) } - xw.WriteUint32(uint32(len(o.Devices))) + m.MarshalUint32(uint32(len(o.Devices))) for i := range o.Devices { - _, err := o.Devices[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Devices[i].MarshalXDRInto(m); err != nil { + return err } } - xw.WriteUint32(o.Flags) + m.MarshalUint32(o.Flags) if l := len(o.Options); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Options", l, 64) + return xdr.ElementSizeExceeded("Options", l, 64) } - xw.WriteUint32(uint32(len(o.Options))) + m.MarshalUint32(uint32(len(o.Options))) for i := range o.Options { - _, err := o.Options[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Options[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *Folder) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *Folder) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Folder) DecodeXDRFrom(xr *xdr.Reader) error { - o.ID = xr.ReadStringMax(256) - _DevicesSize := int(xr.ReadUint32()) +func (o *Folder) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.ID = u.UnmarshalStringMax(256) + _DevicesSize := int(u.UnmarshalUint32()) if _DevicesSize < 0 { return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000) + } else if _DevicesSize == 0 { + o.Devices = nil + } else { + if _DevicesSize > 1000000 { + return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000) + } + if _DevicesSize <= len(o.Devices) { + o.Devices = o.Devices[:_DevicesSize] + } else { + o.Devices = make([]Device, _DevicesSize) + } + for i := range o.Devices { + (&o.Devices[i]).UnmarshalXDRFrom(u) + } } - if _DevicesSize > 1000000 { - return xdr.ElementSizeExceeded("Devices", _DevicesSize, 1000000) - } - o.Devices = make([]Device, _DevicesSize) - for i := range o.Devices { - (&o.Devices[i]).DecodeXDRFrom(xr) - } - o.Flags = xr.ReadUint32() - _OptionsSize := int(xr.ReadUint32()) + o.Flags = u.UnmarshalUint32() + _OptionsSize := int(u.UnmarshalUint32()) if _OptionsSize < 0 { return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } else if _OptionsSize == 0 { + o.Options = nil + } else { + if _OptionsSize > 64 { + return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } + if _OptionsSize <= len(o.Options) { + o.Options = o.Options[:_OptionsSize] + } else { + o.Options = make([]Option, _OptionsSize) + } + for i := range o.Options { + (&o.Options[i]).UnmarshalXDRFrom(u) + } } - if _OptionsSize > 64 { - return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) - } - o.Options = make([]Option, _OptionsSize) - for i := range o.Options { - (&o.Options[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -836,32 +781,26 @@ Device Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of ID | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ ID (variable length) \ +\ ID (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Name (variable length) \ +\ Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Number of Addresses | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Addresses | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Addresses (variable length) \ +/ / +\ Addresses (length + padded data) \ +/ / / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Compression | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Cert Name | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Cert Name (variable length) \ +\ Cert Name (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | @@ -891,13 +830,18 @@ struct Device { */ -func (o Device) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Device) XDRSize() int { + return 4 + len(o.ID) + xdr.Padding(len(o.ID)) + + 4 + len(o.Name) + xdr.Padding(len(o.Name)) + + 4 + xdr.SizeOfSlice(o.Addresses) + 4 + + 4 + len(o.CertName) + xdr.Padding(len(o.CertName)) + 8 + 4 + + 4 + xdr.SizeOfSlice(o.Options) } func (o Device) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Device) MustMarshalXDR() []byte { @@ -908,90 +852,92 @@ func (o Device) MustMarshalXDR() []byte { return bs } -func (o Device) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Device) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Device) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.ID); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) + return xdr.ElementSizeExceeded("ID", l, 32) } - xw.WriteBytes(o.ID) + m.MarshalBytes(o.ID) if l := len(o.Name); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Name", l, 64) + return xdr.ElementSizeExceeded("Name", l, 64) } - xw.WriteString(o.Name) + m.MarshalString(o.Name) if l := len(o.Addresses); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Addresses", l, 64) + return xdr.ElementSizeExceeded("Addresses", l, 64) } - xw.WriteUint32(uint32(len(o.Addresses))) + m.MarshalUint32(uint32(len(o.Addresses))) for i := range o.Addresses { - xw.WriteString(o.Addresses[i]) + m.MarshalString(o.Addresses[i]) } - xw.WriteUint32(o.Compression) + m.MarshalUint32(o.Compression) if l := len(o.CertName); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("CertName", l, 64) + return xdr.ElementSizeExceeded("CertName", l, 64) } - xw.WriteString(o.CertName) - xw.WriteUint64(uint64(o.MaxLocalVersion)) - xw.WriteUint32(o.Flags) + m.MarshalString(o.CertName) + m.MarshalUint64(uint64(o.MaxLocalVersion)) + m.MarshalUint32(o.Flags) if l := len(o.Options); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Options", l, 64) + return xdr.ElementSizeExceeded("Options", l, 64) } - xw.WriteUint32(uint32(len(o.Options))) + m.MarshalUint32(uint32(len(o.Options))) for i := range o.Options { - _, err := o.Options[i].EncodeXDRInto(xw) - if err != nil { - return xw.Tot(), err + if err := o.Options[i].MarshalXDRInto(m); err != nil { + return err } } - return xw.Tot(), xw.Error() -} - -func (o *Device) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + return m.Error } func (o *Device) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Device) DecodeXDRFrom(xr *xdr.Reader) error { - o.ID = xr.ReadBytesMax(32) - o.Name = xr.ReadStringMax(64) - _AddressesSize := int(xr.ReadUint32()) +func (o *Device) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.ID = u.UnmarshalBytesMax(32) + o.Name = u.UnmarshalStringMax(64) + _AddressesSize := int(u.UnmarshalUint32()) if _AddressesSize < 0 { return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 64) + } else if _AddressesSize == 0 { + o.Addresses = nil + } else { + if _AddressesSize > 64 { + return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 64) + } + if _AddressesSize <= len(o.Addresses) { + for i := _AddressesSize; i < len(o.Addresses); i++ { + o.Addresses[i] = "" + } + o.Addresses = o.Addresses[:_AddressesSize] + } else { + o.Addresses = make([]string, _AddressesSize) + } + for i := range o.Addresses { + o.Addresses[i] = u.UnmarshalStringMax(2083) + } } - if _AddressesSize > 64 { - return xdr.ElementSizeExceeded("Addresses", _AddressesSize, 64) - } - o.Addresses = make([]string, _AddressesSize) - for i := range o.Addresses { - o.Addresses[i] = xr.ReadStringMax(2083) - } - o.Compression = xr.ReadUint32() - o.CertName = xr.ReadStringMax(64) - o.MaxLocalVersion = int64(xr.ReadUint64()) - o.Flags = xr.ReadUint32() - _OptionsSize := int(xr.ReadUint32()) + o.Compression = u.UnmarshalUint32() + o.CertName = u.UnmarshalStringMax(64) + o.MaxLocalVersion = int64(u.UnmarshalUint64()) + o.Flags = u.UnmarshalUint32() + _OptionsSize := int(u.UnmarshalUint32()) if _OptionsSize < 0 { return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } else if _OptionsSize == 0 { + o.Options = nil + } else { + if _OptionsSize > 64 { + return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) + } + if _OptionsSize <= len(o.Options) { + o.Options = o.Options[:_OptionsSize] + } else { + o.Options = make([]Option, _OptionsSize) + } + for i := range o.Options { + (&o.Options[i]).UnmarshalXDRFrom(u) + } } - if _OptionsSize > 64 { - return xdr.ElementSizeExceeded("Options", _OptionsSize, 64) - } - o.Options = make([]Option, _OptionsSize) - for i := range o.Options { - (&o.Options[i]).DecodeXDRFrom(xr) - } - return xr.Error() + return u.Error } /* @@ -1001,16 +947,12 @@ Option Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Key | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Key (variable length) \ +\ Key (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Value | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Value (variable length) \ +\ Value (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -1022,13 +964,15 @@ struct Option { */ -func (o Option) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Option) XDRSize() int { + return 4 + len(o.Key) + xdr.Padding(len(o.Key)) + + 4 + len(o.Value) + xdr.Padding(len(o.Value)) } func (o Option) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Option) MustMarshalXDR() []byte { @@ -1039,40 +983,26 @@ func (o Option) MustMarshalXDR() []byte { return bs } -func (o Option) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Option) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o Option) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Key); l > 64 { - return xw.Tot(), xdr.ElementSizeExceeded("Key", l, 64) + return xdr.ElementSizeExceeded("Key", l, 64) } - xw.WriteString(o.Key) + m.MarshalString(o.Key) if l := len(o.Value); l > 1024 { - return xw.Tot(), xdr.ElementSizeExceeded("Value", l, 1024) + return xdr.ElementSizeExceeded("Value", l, 1024) } - xw.WriteString(o.Value) - return xw.Tot(), xw.Error() -} - -func (o *Option) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalString(o.Value) + return m.Error } func (o *Option) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Option) DecodeXDRFrom(xr *xdr.Reader) error { - o.Key = xr.ReadStringMax(64) - o.Value = xr.ReadStringMax(1024) - return xr.Error() +func (o *Option) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Key = u.UnmarshalStringMax(64) + o.Value = u.UnmarshalStringMax(1024) + return u.Error } /* @@ -1082,10 +1012,8 @@ CloseMessage Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Reason | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Reason (variable length) \ +\ Reason (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Code | @@ -1099,13 +1027,14 @@ struct CloseMessage { */ -func (o CloseMessage) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o CloseMessage) XDRSize() int { + return 4 + len(o.Reason) + xdr.Padding(len(o.Reason)) + 4 } func (o CloseMessage) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o CloseMessage) MustMarshalXDR() []byte { @@ -1116,37 +1045,23 @@ func (o CloseMessage) MustMarshalXDR() []byte { return bs } -func (o CloseMessage) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o CloseMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o CloseMessage) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Reason); l > 1024 { - return xw.Tot(), xdr.ElementSizeExceeded("Reason", l, 1024) + return xdr.ElementSizeExceeded("Reason", l, 1024) } - xw.WriteString(o.Reason) - xw.WriteUint32(uint32(o.Code)) - return xw.Tot(), xw.Error() -} - -func (o *CloseMessage) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalString(o.Reason) + m.MarshalUint32(uint32(o.Code)) + return m.Error } func (o *CloseMessage) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *CloseMessage) DecodeXDRFrom(xr *xdr.Reader) error { - o.Reason = xr.ReadStringMax(1024) - o.Code = int32(xr.ReadUint32()) - return xr.Error() +func (o *CloseMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Reason = u.UnmarshalStringMax(1024) + o.Code = int32(u.UnmarshalUint32()) + return u.Error } /* @@ -1160,10 +1075,9 @@ struct EmptyMessage { */ -func (o EmptyMessage) EncodeXDR(w io.Writer) (int, error) { - return 0, nil +func (o EmptyMessage) XDRSize() int { + return 0 } - func (o EmptyMessage) MarshalXDR() ([]byte, error) { return nil, nil } @@ -1172,15 +1086,7 @@ func (o EmptyMessage) MustMarshalXDR() []byte { return nil } -func (o EmptyMessage) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -} - -func (o EmptyMessage) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -} - -func (o *EmptyMessage) DecodeXDR(r io.Reader) error { +func (o EmptyMessage) MarshalXDRInto(m *xdr.Marshaller) error { return nil } @@ -1188,6 +1094,6 @@ func (o *EmptyMessage) UnmarshalXDR(bs []byte) error { return nil } -func (o *EmptyMessage) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() +func (o *EmptyMessage) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil } diff --git a/lib/protocol/protocol.go b/lib/protocol/protocol.go index 334ba28a..c2412230 100644 --- a/lib/protocol/protocol.go +++ b/lib/protocol/protocol.go @@ -12,6 +12,7 @@ import ( "time" lz4 "github.com/bkaradzic/go-lz4" + "github.com/calmh/xdr" ) const ( @@ -130,8 +131,7 @@ type rawConnection struct { pool sync.Pool compression Compression - rdbuf0 []byte // used & reused by readMessage - rdbuf1 []byte // used & reused by readMessage + readerBuf []byte // used & reused by readMessage } type asyncResult struct { @@ -146,7 +146,8 @@ type hdrMsg struct { } type encodable interface { - AppendXDR([]byte) ([]byte, error) + MarshalXDRInto(m *xdr.Marshaller) error + XDRSize() int } type isEofer interface { @@ -374,18 +375,14 @@ func (c *rawConnection) readerLoop() (err error) { } func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) { - if cap(c.rdbuf0) < 8 { - c.rdbuf0 = make([]byte, 8) - } else { - c.rdbuf0 = c.rdbuf0[:8] - } - _, err = io.ReadFull(c.cr, c.rdbuf0) + hdrBuf := make([]byte, 8) + _, err = io.ReadFull(c.cr, hdrBuf) if err != nil { return } - hdr = decodeHeader(binary.BigEndian.Uint32(c.rdbuf0[0:4])) - msglen := int(binary.BigEndian.Uint32(c.rdbuf0[4:8])) + hdr = decodeHeader(binary.BigEndian.Uint32(hdrBuf[:4])) + msglen := int(binary.BigEndian.Uint32(hdrBuf[4:])) l.Debugf("read header %v (msglen=%d)", hdr, msglen) @@ -399,27 +396,40 @@ func (c *rawConnection) readMessage() (hdr header, msg encodable, err error) { return } - if cap(c.rdbuf0) < msglen { - c.rdbuf0 = make([]byte, msglen) + // c.readerBuf contains a buffer we can reuse. But once we've unmarshalled + // a message from the buffer we can't reuse it again as the unmarshalled + // message refers to the contents of the buffer. The only case we a buffer + // ends up in readerBuf for reuse is when the message is compressed, as we + // then decompress into a new buffer instead. + + var msgBuf []byte + if cap(c.readerBuf) >= msglen { + // If we have a buffer ready in rdbuf we just use that. + msgBuf = c.readerBuf[:msglen] } else { - c.rdbuf0 = c.rdbuf0[:msglen] + // Otherwise we allocate a new buffer. + msgBuf = make([]byte, msglen) } - _, err = io.ReadFull(c.cr, c.rdbuf0) + + _, err = io.ReadFull(c.cr, msgBuf) if err != nil { return } - l.Debugf("read %d bytes", len(c.rdbuf0)) + l.Debugf("read %d bytes", len(msgBuf)) - msgBuf := c.rdbuf0 if hdr.compression && msglen > 0 { - c.rdbuf1 = c.rdbuf1[:cap(c.rdbuf1)] - c.rdbuf1, err = lz4.Decode(c.rdbuf1, c.rdbuf0) + // We're going to decompress msgBuf into a different newly allocated + // buffer, so keep msgBuf around for reuse on the next message. + c.readerBuf = msgBuf + + msgBuf, err = lz4.Decode(nil, msgBuf) if err != nil { return } - msgBuf = c.rdbuf1 l.Debugf("decompressed to %d bytes", len(msgBuf)) + } else { + c.readerBuf = nil } if shouldDebug() { @@ -601,7 +611,14 @@ func (c *rawConnection) writerLoop() { case hm := <-c.outbox: if hm.msg != nil { // Uncompressed message in uncBuf - uncBuf, err = hm.msg.AppendXDR(uncBuf[:0]) + msgLen := hm.msg.XDRSize() + if cap(uncBuf) >= msgLen { + uncBuf = uncBuf[:msgLen] + } else { + uncBuf = make([]byte, msgLen) + } + m := &xdr.Marshaller{Data: uncBuf} + err = hm.msg.MarshalXDRInto(m) if hm.done != nil { close(hm.done) } diff --git a/lib/protocol/protocol_test.go b/lib/protocol/protocol_test.go index 96510768..4aa8c670 100644 --- a/lib/protocol/protocol_test.go +++ b/lib/protocol/protocol_test.go @@ -3,7 +3,6 @@ package protocol import ( - "bytes" "encoding/binary" "encoding/hex" "encoding/json" @@ -55,14 +54,13 @@ func TestHeaderMarshalUnmarshal(t *testing.T) { ver = int(uint(ver) % 16) id = int(uint(id) % 4096) typ = int(uint(typ) % 256) - buf := new(bytes.Buffer) - xw := xdr.NewWriter(buf) - h0 := header{version: ver, msgID: id, msgType: typ} - h0.encodeXDR(xw) + buf := make([]byte, 4) + + h0 := header{version: ver, msgID: id, msgType: typ} + h0.MarshalXDRInto(&xdr.Marshaller{Data: buf}) - xr := xdr.NewReader(buf) var h1 header - h1.decodeXDR(xr) + h1.UnmarshalXDRFrom(&xdr.Unmarshaller{Data: buf}) return h0 == h1 } if err := quick.Check(f, nil); err != nil { @@ -128,8 +126,7 @@ func TestVersionErr(t *testing.T) { c0.ClusterConfig(ClusterConfigMessage{}) c1.ClusterConfig(ClusterConfigMessage{}) - w := xdr.NewWriter(c0.cw) - timeoutWriteHeader(w, header{ + timeoutWriteHeader(c0.cw, header{ version: 2, // higher than supported msgID: 0, msgType: messageTypeIndex, @@ -154,8 +151,7 @@ func TestTypeErr(t *testing.T) { c0.ClusterConfig(ClusterConfigMessage{}) c1.ClusterConfig(ClusterConfigMessage{}) - w := xdr.NewWriter(c0.cw) - timeoutWriteHeader(w, header{ + timeoutWriteHeader(c0.cw, header{ version: 0, msgID: 0, msgType: 42, // unknown type @@ -205,7 +201,7 @@ func TestElementSizeExceededNested(t *testing.T) { m := ClusterConfigMessage{ ClientName: "longstringlongstringlongstringinglongstringlongstringlonlongstringlongstringlon", } - _, err := m.EncodeXDR(ioutil.Discard) + _, err := m.MarshalXDR() if err == nil { t.Errorf("ID length %d > max 64, but no error", len(m.Folders[0].ID)) } @@ -213,12 +209,19 @@ func TestElementSizeExceededNested(t *testing.T) { func TestMarshalIndexMessage(t *testing.T) { f := func(m1 IndexMessage) bool { + if len(m1.Options) == 0 { + m1.Options = nil + } for i, f := range m1.Files { m1.Files[i].CachedSize = 0 - for j := range f.Blocks { - f.Blocks[j].Offset = 0 - if len(f.Blocks[j].Hash) == 0 { - f.Blocks[j].Hash = nil + if len(f.Blocks) == 0 { + m1.Files[i].Blocks = nil + } else { + for j := range f.Blocks { + f.Blocks[j].Offset = 0 + if len(f.Blocks[j].Hash) == 0 { + f.Blocks[j].Hash = nil + } } } } @@ -233,6 +236,9 @@ func TestMarshalIndexMessage(t *testing.T) { func TestMarshalRequestMessage(t *testing.T) { f := func(m1 RequestMessage) bool { + if len(m1.Options) == 0 { + m1.Options = nil + } return testMarshal(t, "request", &m1, &RequestMessage{}) } @@ -256,6 +262,9 @@ func TestMarshalResponseMessage(t *testing.T) { func TestMarshalClusterConfigMessage(t *testing.T) { f := func(m1 ClusterConfigMessage) bool { + if len(m1.Options) == 0 { + m1.Options = nil + } return testMarshal(t, "clusterconfig", &m1, &ClusterConfigMessage{}) } @@ -275,13 +284,11 @@ func TestMarshalCloseMessage(t *testing.T) { } type message interface { - EncodeXDR(io.Writer) (int, error) - DecodeXDR(io.Reader) error + MarshalXDR() ([]byte, error) + UnmarshalXDR([]byte) error } func testMarshal(t *testing.T, prefix string, m1, m2 message) bool { - var buf bytes.Buffer - failed := func(bc []byte) { bs, _ := json.MarshalIndent(m1, "", " ") ioutil.WriteFile(prefix+"-1.txt", bs, 0644) @@ -294,7 +301,7 @@ func testMarshal(t *testing.T, prefix string, m1, m2 message) bool { } } - _, err := m1.EncodeXDR(&buf) + buf, err := m1.MarshalXDR() if err != nil && strings.Contains(err.Error(), "exceeds size") { return true } @@ -303,23 +310,20 @@ func testMarshal(t *testing.T, prefix string, m1, m2 message) bool { t.Fatal(err) } - bc := make([]byte, len(buf.Bytes())) - copy(bc, buf.Bytes()) - - err = m2.DecodeXDR(&buf) + err = m2.UnmarshalXDR(buf) if err != nil { - failed(bc) + failed(buf) t.Fatal(err) } ok := reflect.DeepEqual(m1, m2) if !ok { - failed(bc) + failed(buf) } return ok } -func timeoutWriteHeader(w *xdr.Writer, hdr header) { +func timeoutWriteHeader(w io.Writer, hdr header) { // This tries to write a message header to w, but times out after a while. // This is useful because in testing, with a PipeWriter, it will block // forever if the other side isn't reading any more. On the other hand we @@ -332,8 +336,7 @@ func timeoutWriteHeader(w *xdr.Writer, hdr header) { done := make(chan struct{}) go func() { - w.WriteRaw(buf[:]) - l.Infoln("write completed") + w.Write(buf[:]) close(done) }() select { diff --git a/lib/protocol/vector_xdr.go b/lib/protocol/vector_xdr.go index 17dacbc7..7b9089fb 100644 --- a/lib/protocol/vector_xdr.go +++ b/lib/protocol/vector_xdr.go @@ -7,37 +7,29 @@ import "github.com/calmh/xdr" // This stuff is hacked up manually because genxdr doesn't support 'type // Vector []Counter' declarations and it was tricky when I tried to add it... -type xdrWriter interface { - WriteUint32(uint32) (int, error) - WriteUint64(uint64) (int, error) -} -type xdrReader interface { - ReadUint32() uint32 - ReadUint64() uint64 -} - -// EncodeXDRInto encodes the vector as an XDR object into the given XDR -// encoder. -func (v Vector) EncodeXDRInto(w xdrWriter) (int, error) { - w.WriteUint32(uint32(len(v))) +func (v Vector) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(uint32(len(v))) for i := range v { - w.WriteUint64(uint64(v[i].ID)) - w.WriteUint64(v[i].Value) + m.MarshalUint64(uint64(v[i].ID)) + m.MarshalUint64(v[i].Value) } - return 4 + 16*len(v), nil + return m.Error } -// DecodeXDRFrom decodes the XDR objects from the given reader into itself. -func (v *Vector) DecodeXDRFrom(r xdrReader) error { - l := int(r.ReadUint32()) +func (v *Vector) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + l := int(u.UnmarshalUint32()) if l > 1e6 { return xdr.ElementSizeExceeded("number of counters", l, 1e6) } n := make(Vector, l) for i := range n { - n[i].ID = ShortID(r.ReadUint64()) - n[i].Value = r.ReadUint64() + n[i].ID = ShortID(u.UnmarshalUint64()) + n[i].Value = u.UnmarshalUint64() } *v = n - return nil + return u.Error +} + +func (v Vector) XDRSize() int { + return 4 + 16*len(v) } diff --git a/lib/relay/protocol/packets_xdr.go b/lib/relay/protocol/packets_xdr.go index 9eef6c0f..dcbe013c 100644 --- a/lib/relay/protocol/packets_xdr.go +++ b/lib/relay/protocol/packets_xdr.go @@ -5,9 +5,6 @@ package protocol import ( - "bytes" - "io" - "github.com/calmh/xdr" ) @@ -34,13 +31,14 @@ struct header { */ -func (o header) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o header) XDRSize() int { + return 4 + 4 + 4 } func (o header) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o header) MustMarshalXDR() []byte { @@ -51,36 +49,22 @@ func (o header) MustMarshalXDR() []byte { return bs } -func (o header) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o header) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteUint32(o.magic) - xw.WriteUint32(uint32(o.messageType)) - xw.WriteUint32(uint32(o.messageLength)) - return xw.Tot(), xw.Error() -} - -func (o *header) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) +func (o header) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(o.magic) + m.MarshalUint32(uint32(o.messageType)) + m.MarshalUint32(uint32(o.messageLength)) + return m.Error } func (o *header) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *header) DecodeXDRFrom(xr *xdr.Reader) error { - o.magic = xr.ReadUint32() - o.messageType = int32(xr.ReadUint32()) - o.messageLength = int32(xr.ReadUint32()) - return xr.Error() +func (o *header) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.magic = u.UnmarshalUint32() + o.messageType = int32(u.UnmarshalUint32()) + o.messageLength = int32(u.UnmarshalUint32()) + return u.Error } /* @@ -94,10 +78,9 @@ struct Ping { */ -func (o Ping) EncodeXDR(w io.Writer) (int, error) { - return 0, nil +func (o Ping) XDRSize() int { + return 0 } - func (o Ping) MarshalXDR() ([]byte, error) { return nil, nil } @@ -106,15 +89,7 @@ func (o Ping) MustMarshalXDR() []byte { return nil } -func (o Ping) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -} - -func (o Ping) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -} - -func (o *Ping) DecodeXDR(r io.Reader) error { +func (o Ping) MarshalXDRInto(m *xdr.Marshaller) error { return nil } @@ -122,8 +97,8 @@ func (o *Ping) UnmarshalXDR(bs []byte) error { return nil } -func (o *Ping) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() +func (o *Ping) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil } /* @@ -137,10 +112,9 @@ struct Pong { */ -func (o Pong) EncodeXDR(w io.Writer) (int, error) { - return 0, nil +func (o Pong) XDRSize() int { + return 0 } - func (o Pong) MarshalXDR() ([]byte, error) { return nil, nil } @@ -149,15 +123,7 @@ func (o Pong) MustMarshalXDR() []byte { return nil } -func (o Pong) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -} - -func (o Pong) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -} - -func (o *Pong) DecodeXDR(r io.Reader) error { +func (o Pong) MarshalXDRInto(m *xdr.Marshaller) error { return nil } @@ -165,8 +131,8 @@ func (o *Pong) UnmarshalXDR(bs []byte) error { return nil } -func (o *Pong) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() +func (o *Pong) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil } /* @@ -180,10 +146,9 @@ struct JoinRelayRequest { */ -func (o JoinRelayRequest) EncodeXDR(w io.Writer) (int, error) { - return 0, nil +func (o JoinRelayRequest) XDRSize() int { + return 0 } - func (o JoinRelayRequest) MarshalXDR() ([]byte, error) { return nil, nil } @@ -192,15 +157,7 @@ func (o JoinRelayRequest) MustMarshalXDR() []byte { return nil } -func (o JoinRelayRequest) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -} - -func (o JoinRelayRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -} - -func (o *JoinRelayRequest) DecodeXDR(r io.Reader) error { +func (o JoinRelayRequest) MarshalXDRInto(m *xdr.Marshaller) error { return nil } @@ -208,8 +165,8 @@ func (o *JoinRelayRequest) UnmarshalXDR(bs []byte) error { return nil } -func (o *JoinRelayRequest) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() +func (o *JoinRelayRequest) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil } /* @@ -223,10 +180,9 @@ struct RelayFull { */ -func (o RelayFull) EncodeXDR(w io.Writer) (int, error) { - return 0, nil +func (o RelayFull) XDRSize() int { + return 0 } - func (o RelayFull) MarshalXDR() ([]byte, error) { return nil, nil } @@ -235,15 +191,7 @@ func (o RelayFull) MustMarshalXDR() []byte { return nil } -func (o RelayFull) AppendXDR(bs []byte) ([]byte, error) { - return bs, nil -} - -func (o RelayFull) EncodeXDRInto(xw *xdr.Writer) (int, error) { - return xw.Tot(), xw.Error() -} - -func (o *RelayFull) DecodeXDR(r io.Reader) error { +func (o RelayFull) MarshalXDRInto(m *xdr.Marshaller) error { return nil } @@ -251,8 +199,8 @@ func (o *RelayFull) UnmarshalXDR(bs []byte) error { return nil } -func (o *RelayFull) DecodeXDRFrom(xr *xdr.Reader) error { - return xr.Error() +func (o *RelayFull) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + return nil } /* @@ -262,10 +210,8 @@ JoinSessionRequest Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Key | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Key (variable length) \ +\ Key (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -276,13 +222,14 @@ struct JoinSessionRequest { */ -func (o JoinSessionRequest) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o JoinSessionRequest) XDRSize() int { + return 4 + len(o.Key) + xdr.Padding(len(o.Key)) } func (o JoinSessionRequest) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o JoinSessionRequest) MustMarshalXDR() []byte { @@ -293,35 +240,21 @@ func (o JoinSessionRequest) MustMarshalXDR() []byte { return bs } -func (o JoinSessionRequest) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o JoinSessionRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o JoinSessionRequest) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.Key); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("Key", l, 32) + return xdr.ElementSizeExceeded("Key", l, 32) } - xw.WriteBytes(o.Key) - return xw.Tot(), xw.Error() -} - -func (o *JoinSessionRequest) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalBytes(o.Key) + return m.Error } func (o *JoinSessionRequest) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *JoinSessionRequest) DecodeXDRFrom(xr *xdr.Reader) error { - o.Key = xr.ReadBytesMax(32) - return xr.Error() +func (o *JoinSessionRequest) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Key = u.UnmarshalBytesMax(32) + return u.Error } /* @@ -333,10 +266,8 @@ Response Structure: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Code | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Message | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Message (variable length) \ +\ Message (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -348,13 +279,15 @@ struct Response { */ -func (o Response) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o Response) XDRSize() int { + return 4 + + 4 + len(o.Message) + xdr.Padding(len(o.Message)) } func (o Response) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o Response) MustMarshalXDR() []byte { @@ -365,34 +298,20 @@ func (o Response) MustMarshalXDR() []byte { return bs } -func (o Response) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o Response) EncodeXDRInto(xw *xdr.Writer) (int, error) { - xw.WriteUint32(uint32(o.Code)) - xw.WriteString(o.Message) - return xw.Tot(), xw.Error() -} - -func (o *Response) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) +func (o Response) MarshalXDRInto(m *xdr.Marshaller) error { + m.MarshalUint32(uint32(o.Code)) + m.MarshalString(o.Message) + return m.Error } func (o *Response) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *Response) DecodeXDRFrom(xr *xdr.Reader) error { - o.Code = int32(xr.ReadUint32()) - o.Message = xr.ReadString() - return xr.Error() +func (o *Response) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.Code = int32(u.UnmarshalUint32()) + o.Message = u.UnmarshalString() + return u.Error } /* @@ -402,10 +321,8 @@ ConnectRequest Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of ID | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ ID (variable length) \ +\ ID (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -416,13 +333,14 @@ struct ConnectRequest { */ -func (o ConnectRequest) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o ConnectRequest) XDRSize() int { + return 4 + len(o.ID) + xdr.Padding(len(o.ID)) } func (o ConnectRequest) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o ConnectRequest) MustMarshalXDR() []byte { @@ -433,35 +351,21 @@ func (o ConnectRequest) MustMarshalXDR() []byte { return bs } -func (o ConnectRequest) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o ConnectRequest) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o ConnectRequest) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.ID); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("ID", l, 32) + return xdr.ElementSizeExceeded("ID", l, 32) } - xw.WriteBytes(o.ID) - return xw.Tot(), xw.Error() -} - -func (o *ConnectRequest) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalBytes(o.ID) + return m.Error } func (o *ConnectRequest) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *ConnectRequest) DecodeXDRFrom(xr *xdr.Reader) error { - o.ID = xr.ReadBytesMax(32) - return xr.Error() +func (o *ConnectRequest) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.ID = u.UnmarshalBytesMax(32) + return u.Error } /* @@ -471,25 +375,19 @@ SessionInvitation Structure: 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of From | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ From (variable length) \ +\ From (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Key | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Key (variable length) \ +\ Key (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| Length of Address | -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ / / -\ Address (variable length) \ +\ Address (length + padded data) \ / / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -| 0x0000 | Port | +| 16 zero bits | Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Server Socket (V=0 or 1) |V| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -505,13 +403,16 @@ struct SessionInvitation { */ -func (o SessionInvitation) EncodeXDR(w io.Writer) (int, error) { - var xw = xdr.NewWriter(w) - return o.EncodeXDRInto(xw) +func (o SessionInvitation) XDRSize() int { + return 4 + len(o.From) + xdr.Padding(len(o.From)) + + 4 + len(o.Key) + xdr.Padding(len(o.Key)) + + 4 + len(o.Address) + xdr.Padding(len(o.Address)) + 4 + 4 } func (o SessionInvitation) MarshalXDR() ([]byte, error) { - return o.AppendXDR(make([]byte, 0, 128)) + buf := make([]byte, o.XDRSize()) + m := &xdr.Marshaller{Data: buf} + return buf, o.MarshalXDRInto(m) } func (o SessionInvitation) MustMarshalXDR() []byte { @@ -522,47 +423,33 @@ func (o SessionInvitation) MustMarshalXDR() []byte { return bs } -func (o SessionInvitation) AppendXDR(bs []byte) ([]byte, error) { - var aw = xdr.AppendWriter(bs) - var xw = xdr.NewWriter(&aw) - _, err := o.EncodeXDRInto(xw) - return []byte(aw), err -} - -func (o SessionInvitation) EncodeXDRInto(xw *xdr.Writer) (int, error) { +func (o SessionInvitation) MarshalXDRInto(m *xdr.Marshaller) error { if l := len(o.From); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("From", l, 32) + return xdr.ElementSizeExceeded("From", l, 32) } - xw.WriteBytes(o.From) + m.MarshalBytes(o.From) if l := len(o.Key); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("Key", l, 32) + return xdr.ElementSizeExceeded("Key", l, 32) } - xw.WriteBytes(o.Key) + m.MarshalBytes(o.Key) if l := len(o.Address); l > 32 { - return xw.Tot(), xdr.ElementSizeExceeded("Address", l, 32) + return xdr.ElementSizeExceeded("Address", l, 32) } - xw.WriteBytes(o.Address) - xw.WriteUint16(o.Port) - xw.WriteBool(o.ServerSocket) - return xw.Tot(), xw.Error() -} - -func (o *SessionInvitation) DecodeXDR(r io.Reader) error { - xr := xdr.NewReader(r) - return o.DecodeXDRFrom(xr) + m.MarshalBytes(o.Address) + m.MarshalUint16(o.Port) + m.MarshalBool(o.ServerSocket) + return m.Error } func (o *SessionInvitation) UnmarshalXDR(bs []byte) error { - var br = bytes.NewReader(bs) - var xr = xdr.NewReader(br) - return o.DecodeXDRFrom(xr) + u := &xdr.Unmarshaller{Data: bs} + return o.UnmarshalXDRFrom(u) } - -func (o *SessionInvitation) DecodeXDRFrom(xr *xdr.Reader) error { - o.From = xr.ReadBytesMax(32) - o.Key = xr.ReadBytesMax(32) - o.Address = xr.ReadBytesMax(32) - o.Port = xr.ReadUint16() - o.ServerSocket = xr.ReadBool() - return xr.Error() +func (o *SessionInvitation) UnmarshalXDRFrom(u *xdr.Unmarshaller) error { + o.From = u.UnmarshalBytesMax(32) + o.Key = u.UnmarshalBytesMax(32) + o.Address = u.UnmarshalBytesMax(32) + o.Port = u.UnmarshalUint16() + o.ServerSocket = u.UnmarshalBool() + return u.Error } diff --git a/lib/relay/protocol/protocol.go b/lib/relay/protocol/protocol.go index dad76d94..2a7339e1 100644 --- a/lib/relay/protocol/protocol.go +++ b/lib/relay/protocol/protocol.go @@ -74,7 +74,13 @@ func WriteMessage(w io.Writer, message interface{}) error { func ReadMessage(r io.Reader) (interface{}, error) { var header header - if err := header.DecodeXDR(r); err != nil { + + buf := make([]byte, header.XDRSize()) + if _, err := io.ReadFull(r, buf); err != nil { + return nil, err + } + + if err := header.UnmarshalXDR(buf); err != nil { return nil, err } @@ -82,38 +88,43 @@ func ReadMessage(r io.Reader) (interface{}, error) { return nil, fmt.Errorf("magic mismatch") } + buf = make([]byte, int(header.messageLength)) + if _, err := io.ReadFull(r, buf); err != nil { + return nil, err + } + switch header.messageType { case messageTypePing: var msg Ping - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypePong: var msg Pong - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeJoinRelayRequest: var msg JoinRelayRequest - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeJoinSessionRequest: var msg JoinSessionRequest - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeResponse: var msg Response - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeConnectRequest: var msg ConnectRequest - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeSessionInvitation: var msg SessionInvitation - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err case messageTypeRelayFull: var msg RelayFull - err := msg.DecodeXDR(r) + err := msg.UnmarshalXDR(buf) return msg, err }