From a87bbc6e8637e910fc81cde0f0ee1ab40347ffbd Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 14 Jun 2016 12:45:47 +0200 Subject: Dict MUST be sorted --- bencode/bencode.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'bencode/bencode.go') diff --git a/bencode/bencode.go b/bencode/bencode.go index 2c2bdfc..244fc66 100644 --- a/bencode/bencode.go +++ b/bencode/bencode.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "reflect" + "sort" "strconv" "strings" "time" @@ -64,22 +65,32 @@ func marshalDict(out io.Writer, v reflect.Value) { marshalInt(out, val.Unix()) default: t := v.Type() - io.WriteString(out, "d") + names := make([]string, t.NumField()) for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - tag := f.Tag.Get("bencode") + names[i] = t.Field(i).Name + } + sort.Sort(sort.StringSlice(names)) + + io.WriteString(out, "d") + for _, n := range names { + tf, ok := t.FieldByName(n) + if !ok { + continue + } + tag := tf.Tag.Get("bencode") if tag == "-" { continue } name, param := parseTag(tag) if name == "" { - name = f.Name + name = n } - if param == "optional" && isEmpty(v.Field(i)) { + vf := v.FieldByName(n) + if param == "optional" && isEmpty(vf) { continue } marshalString(out, name) - marshalField(out, v.Field(i)) + marshalField(out, vf) } io.WriteString(out, "e") } -- cgit v1.2.3 From 8c2becf66ba5a927564f13cb8e69f8bd6b972887 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Tue, 14 Jun 2016 13:13:29 +0200 Subject: Simplify marshalDict --- bencode/bencode.go | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'bencode/bencode.go') diff --git a/bencode/bencode.go b/bencode/bencode.go index 244fc66..e761940 100644 --- a/bencode/bencode.go +++ b/bencode/bencode.go @@ -59,33 +59,35 @@ 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() - names := make([]string, t.NumField()) + fields := make([]reflect.StructField, t.NumField()) for i := 0; i < t.NumField(); i++ { - names[i] = t.Field(i).Name + fields[i] = t.Field(i) } - sort.Sort(sort.StringSlice(names)) + sort.Sort(byName(fields)) io.WriteString(out, "d") - for _, n := range names { - tf, ok := t.FieldByName(n) - if !ok { - continue - } - tag := tf.Tag.Get("bencode") + for _, n := range fields { + tag := n.Tag.Get("bencode") if tag == "-" { continue } name, param := parseTag(tag) if name == "" { - name = n + name = n.Name } - vf := v.FieldByName(n) + vf := v.FieldByIndex(n.Index) if param == "optional" && isEmpty(vf) { continue } -- cgit v1.2.3