Skip to content

Commit d50c380

Browse files
committed
Merge pull request #100 from cbusbey/unmarshal_group_fix
fixes bug in unmarshalling group components
2 parents 827248e + b2fb4e8 commit d50c380

File tree

4 files changed

+58
-42
lines changed

4 files changed

+58
-42
lines changed

marshal.go

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ package quickfix
22

33
import (
44
"reflect"
5-
"strconv"
6-
"strings"
75
"time"
86
)
97

@@ -66,38 +64,7 @@ func (e encoder) encodeValue(fixTag Tag, v reflect.Value, omitEmpty bool, defaul
6664
panic("repeating group must be a slice of type struct")
6765
}
6866

69-
template := make(GroupTemplate, 0)
70-
71-
var walkFunc func(t reflect.Type)
72-
73-
walkFunc = func(t reflect.Type) {
74-
for i := 0; i < t.NumField(); i++ {
75-
sf := t.Field(i)
76-
77-
//recurse if item is a component, optional or not
78-
elementType := sf.Type
79-
if elementType.Kind() == reflect.Ptr {
80-
elementType = elementType.Elem()
81-
}
82-
83-
if elementType.Kind() == reflect.Struct {
84-
walkFunc(elementType)
85-
continue
86-
}
87-
88-
afixTag, err := strconv.Atoi(strings.Split(sf.Tag.Get("fix"), ",")[0])
89-
90-
if err != nil {
91-
panic(err)
92-
}
93-
94-
template = append(template, GroupElement(Tag(afixTag)))
95-
}
96-
}
97-
98-
walkFunc(elem)
99-
100-
repeatingGroup := RepeatingGroup{Tag: fixTag, GroupTemplate: template}
67+
repeatingGroup := RepeatingGroup{Tag: fixTag, GroupTemplate: buildGroupTemplate(elem)}
10168

10269
for i := 0; i < v.Len(); i++ {
10370
group := repeatingGroup.Add()

reflection.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package quickfix
22

33
import (
4+
"reflect"
45
"strconv"
56
"strings"
67
)
@@ -28,3 +29,32 @@ func parseStructTag(goTag string) (tag Tag, omitEmpty bool, defaultVal *string)
2829

2930
return
3031
}
32+
33+
func buildGroupTemplate(elem reflect.Type) GroupTemplate {
34+
template := make(GroupTemplate, 0)
35+
36+
var walkFunc func(t reflect.Type)
37+
38+
walkFunc = func(t reflect.Type) {
39+
for i := 0; i < t.NumField(); i++ {
40+
sf := t.Field(i)
41+
42+
//recurse if item is a component, optional or not
43+
elementType := sf.Type
44+
if elementType.Kind() == reflect.Ptr {
45+
elementType = elementType.Elem()
46+
}
47+
48+
if elementType.Kind() == reflect.Struct {
49+
walkFunc(elementType)
50+
continue
51+
}
52+
53+
afixTag, _, _ := parseStructTag(sf.Tag.Get("fix"))
54+
template = append(template, GroupElement(Tag(afixTag)))
55+
}
56+
}
57+
58+
walkFunc(elem)
59+
return template
60+
}

unmarshal.go

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,8 @@ func (d decoder) decodeValue(fixTag Tag, t reflect.Type, v reflect.Value) Messag
5353
if elem.Kind() != reflect.Struct {
5454
panic("repeating group must be a slice of type struct")
5555
}
56-
template := make(GroupTemplate, elem.NumField())
57-
for i := 0; i < elem.NumField(); i++ {
58-
sf := elem.Field(i)
59-
fixTag, _, _ := parseStructTag(sf.Tag.Get("fix"))
60-
template[i] = GroupElement(fixTag)
61-
}
62-
repeatingGroup := RepeatingGroup{Tag: fixTag, GroupTemplate: template}
56+
57+
repeatingGroup := RepeatingGroup{Tag: fixTag, GroupTemplate: buildGroupTemplate(elem)}
6358
if err := d.FieldMap.GetGroup(&repeatingGroup); err != nil {
6459
return err
6560
}

unmarshal_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package quickfix_test
22

33
import (
4-
"github.com/quickfixgo/quickfix"
54
"testing"
65
"time"
6+
7+
"github.com/quickfixgo/quickfix"
78
)
89

910
func TestUnmarshal_Literals(t *testing.T) {
@@ -140,9 +141,22 @@ func TestUnmarshal_RepeatingGroups(t *testing.T) {
140141
StringField2 *string `fix:"9"`
141142
}
142143

144+
type AnonymousGroup struct {
145+
IntField3 int `fix:"3"`
146+
}
147+
148+
type GroupComponent1 struct {
149+
}
150+
151+
type GroupComponent2 struct {
152+
}
153+
143154
type Group2 struct {
144155
IntField1 int `fix:"1"`
145156
IntField2 int `fix:"2"`
157+
AnonymousGroup
158+
GroupComponent1
159+
OptionalComponent *GroupComponent2
146160
}
147161

148162
type Message struct {
@@ -160,12 +174,22 @@ func TestUnmarshal_RepeatingGroups(t *testing.T) {
160174
quickfix.GroupElement(quickfix.Tag(9)),
161175
}
162176

177+
group2Template := quickfix.GroupTemplate{
178+
quickfix.GroupElement(quickfix.Tag(1)),
179+
quickfix.GroupElement(quickfix.Tag(2)),
180+
quickfix.GroupElement(quickfix.Tag(3)),
181+
}
182+
163183
group1 := quickfix.RepeatingGroup{Tag: quickfix.Tag(100), GroupTemplate: group1Template}
164184
group1.Add().SetField(quickfix.Tag(8), quickfix.FIXString("hello")).SetField(quickfix.Tag(9), quickfix.FIXString("world"))
165185
group1.Add().SetField(quickfix.Tag(8), quickfix.FIXString("goodbye"))
166186
group1.Add().SetField(quickfix.Tag(8), quickfix.FIXString("OHHAI")).SetField(quickfix.Tag(9), quickfix.FIXString("world"))
167187
fixMsg.Body.SetGroup(group1)
168188

189+
group2 := quickfix.RepeatingGroup{Tag: quickfix.Tag(101), GroupTemplate: group2Template}
190+
group2.Add().SetField(quickfix.Tag(1), quickfix.FIXInt(1)).SetField(quickfix.Tag(2), quickfix.FIXInt(2))
191+
fixMsg.Body.SetGroup(group2)
192+
169193
var msgOut Message
170194
quickfix.Unmarshal(fixMsg, &msgOut)
171195

0 commit comments

Comments
 (0)