aboutsummaryrefslogtreecommitdiff
path: root/bencode
diff options
context:
space:
mode:
Diffstat (limited to 'bencode')
-rw-r--r--bencode/bencode.go25
1 files changed, 19 insertions, 6 deletions
diff --git a/bencode/bencode.go b/bencode/bencode.go
index c8840fd..2521287 100644
--- a/bencode/bencode.go
+++ b/bencode/bencode.go
@@ -7,6 +7,7 @@ import (
"fmt"
"io"
"reflect"
+ "sort"
"strconv"
"strings"
"time"
@@ -58,28 +59,40 @@ func isEmpty(v reflect.Value) bool {
return false
}
+type byName []reflect.StructField
+
+func (n byName) Len() int { return len(n) }
+func (n byName) Less(i, j int) bool { return n[i].Name < n[j].Name }
+func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] }
+
func marshalDict(out io.Writer, v reflect.Value) {
switch val := v.Interface().(type) {
case time.Time:
marshalInt(out, val.Unix())
default:
t := v.Type()
- io.WriteString(out, "d")
+ fields := make([]reflect.StructField, t.NumField())
for i := 0; i < t.NumField(); i++ {
- f := t.Field(i)
- tag := f.Tag.Get("bencode")
+ fields[i] = t.Field(i)
+ }
+ sort.Sort(byName(fields))
+
+ io.WriteString(out, "d")
+ for _, n := range fields {
+ tag := n.Tag.Get("bencode")
if tag == "-" {
continue
}
name, param := parseTag(tag)
if name == "" {
- name = f.Name
+ name = n.Name
}
- if param == "optional" && isEmpty(v.Field(i)) {
+ vf := v.FieldByIndex(n.Index)
+ if param == "optional" && isEmpty(vf) {
continue
}
marshalString(out, name)
- marshalField(out, v.Field(i))
+ marshalField(out, vf)
}
io.WriteString(out, "e")
}