Skip to content

Commit 9628840

Browse files
author
Chris Busbey
committed
use data dictionary for parsing fix messages
1 parent 98b515f commit 9628840

File tree

6 files changed

+72
-12
lines changed

6 files changed

+72
-12
lines changed

in_session.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ func (state inSession) resendMessages(session *session, beginSeqNo, endSeqNo int
213213
nextSeqNum := seqNum
214214
msg := NewMessage()
215215
for _, msgBytes := range msgs {
216-
_ = ParseMessage(msg, bytes.NewBuffer(msgBytes))
216+
_ = ParseMessageWithDataDictionary(msg, bytes.NewBuffer(msgBytes), session.transportDataDictionary, session.appDataDictionary)
217217
msgType, _ := msg.Header.GetBytes(tagMsgType)
218218
sentMessageSeqNum, _ := msg.Header.GetInt(tagMsgSeqNum)
219219

message.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"math"
77
"time"
88

9+
"github.com/quickfixgo/quickfix/datadictionary"
910
"github.com/quickfixgo/quickfix/enum"
1011
)
1112

@@ -116,6 +117,16 @@ func NewMessage() *Message {
116117

117118
//ParseMessage constructs a Message from a byte slice wrapping a FIX message.
118119
func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
120+
return ParseMessageWithDataDictionary(msg, rawMessage, nil, nil)
121+
}
122+
123+
//ParseMessageWithDataDictionary constructs a Message from a byte slice wrapping a FIX message using an optional session and application DataDictionary for reference.
124+
func ParseMessageWithDataDictionary(
125+
msg *Message,
126+
rawMessage *bytes.Buffer,
127+
transportDataDictionary *datadictionary.DataDictionary,
128+
applicationDataDictionary *datadictionary.DataDictionary,
129+
) (err error) {
119130
msg.Header.Clear()
120131
msg.Body.Clear()
121132
msg.Trailer.Clear()
@@ -173,9 +184,9 @@ func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
173184
}
174185

175186
switch {
176-
case parsedFieldBytes.tag.IsHeader():
187+
case isHeaderField(parsedFieldBytes.tag, transportDataDictionary):
177188
msg.Header.add(msg.fields[fieldIndex : fieldIndex+1])
178-
case parsedFieldBytes.tag.IsTrailer():
189+
case isTrailerField(parsedFieldBytes.tag, transportDataDictionary):
179190
msg.Trailer.add(msg.fields[fieldIndex : fieldIndex+1])
180191
default:
181192
foundBody = true
@@ -215,6 +226,33 @@ func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
215226
}
216227

217228
return
229+
230+
}
231+
232+
func isHeaderField(tag Tag, dataDict *datadictionary.DataDictionary) bool {
233+
if tag.IsHeader() {
234+
return true
235+
}
236+
237+
if dataDict == nil {
238+
return false
239+
}
240+
241+
_, ok := dataDict.Header.Fields[int(tag)]
242+
return ok
243+
}
244+
245+
func isTrailerField(tag Tag, dataDict *datadictionary.DataDictionary) bool {
246+
if tag.IsTrailer() {
247+
return true
248+
}
249+
250+
if dataDict == nil {
251+
return false
252+
}
253+
254+
_, ok := dataDict.Trailer.Fields[int(tag)]
255+
return ok
218256
}
219257

220258
// MsgType returns MsgType (tag 35) field's value

message_test.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"bytes"
55
"testing"
66

7+
"github.com/quickfixgo/quickfix/datadictionary"
78
"github.com/quickfixgo/quickfix/enum"
89
"github.com/stretchr/testify/suite"
910
)
@@ -18,7 +19,7 @@ func BenchmarkParseMessage(b *testing.B) {
1819
}
1920

2021
type MessageSuite struct {
21-
suite.Suite
22+
QuickFIXSuite
2223
msg *Message
2324
}
2425

@@ -53,6 +54,26 @@ func (s *MessageSuite) TestParseMessage() {
5354
s.False(s.msg.IsMsgTypeOf(enum.MsgType_LOGON))
5455
}
5556

57+
func (s *MessageSuite) TestParseMessageWithDataDictionary() {
58+
dict := new(datadictionary.DataDictionary)
59+
dict.Header = &datadictionary.MessageDef{
60+
Fields: map[int]*datadictionary.FieldDef{
61+
10030: nil,
62+
},
63+
}
64+
dict.Trailer = &datadictionary.MessageDef{
65+
Fields: map[int]*datadictionary.FieldDef{
66+
5050: nil,
67+
},
68+
}
69+
rawMsg := bytes.NewBufferString("8=FIX.4.29=12635=D34=249=TW52=20140515-19:49:56.65956=ISLD10030=CUST11=10021=140=154=155=TSLA60=00010101-00:00:00.0005050=HELLO10=039")
70+
71+
err := ParseMessageWithDataDictionary(s.msg, rawMsg, dict, dict)
72+
s.Nil(err)
73+
s.FieldEquals(Tag(10030), "CUST", s.msg.Header)
74+
s.FieldEquals(Tag(5050), "HELLO", s.msg.Trailer)
75+
}
76+
5677
func (s *MessageSuite) TestParseOutOfOrder() {
5778
//allow fields out of order, save for validation
5879
rawMsg := bytes.NewBufferString("8=FIX.4.09=8135=D11=id21=338=10040=154=155=MSFT34=249=TW52=20140521-22:07:0956=ISLD10=250")

session.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sync"
88
"time"
99

10+
"github.com/quickfixgo/quickfix/datadictionary"
1011
"github.com/quickfixgo/quickfix/enum"
1112
"github.com/quickfixgo/quickfix/internal"
1213
)
@@ -40,6 +41,8 @@ type session struct {
4041

4142
admin chan interface{}
4243
internal.SessionSettings
44+
transportDataDictionary *datadictionary.DataDictionary
45+
appDataDictionary *datadictionary.DataDictionary
4346

4447
messagePool
4548
}

session_factory.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -97,29 +97,27 @@ func (f sessionFactory) newSession(
9797
return
9898
}
9999

100-
var transportDataDictionary, appDataDictionary *datadictionary.DataDictionary
101-
if transportDataDictionary, err = datadictionary.Parse(transportDataDictionaryPath); err != nil {
100+
if s.transportDataDictionary, err = datadictionary.Parse(transportDataDictionaryPath); err != nil {
102101
return
103102
}
104103

105-
if appDataDictionary, err = datadictionary.Parse(appDataDictionaryPath); err != nil {
104+
if s.appDataDictionary, err = datadictionary.Parse(appDataDictionaryPath); err != nil {
106105
return
107106
}
108107

109-
s.validator = &fixtValidator{transportDataDictionary, appDataDictionary, validatorSettings}
108+
s.validator = &fixtValidator{s.transportDataDictionary, s.appDataDictionary, validatorSettings}
110109
}
111110
} else if settings.HasSetting(config.DataDictionary) {
112111
var dataDictionaryPath string
113112
if dataDictionaryPath, err = settings.Setting(config.DataDictionary); err != nil {
114113
return
115114
}
116115

117-
var dataDictionary *datadictionary.DataDictionary
118-
if dataDictionary, err = datadictionary.Parse(dataDictionaryPath); err != nil {
116+
if s.appDataDictionary, err = datadictionary.Parse(dataDictionaryPath); err != nil {
119117
return
120118
}
121119

122-
s.validator = &fixValidator{dataDictionary, validatorSettings}
120+
s.validator = &fixValidator{s.appDataDictionary, validatorSettings}
123121
}
124122

125123
if settings.HasSetting(config.ResetOnLogon) {

session_state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ func (sm *stateMachine) Incoming(session *session, m fixIn) {
7070
session.log.OnIncoming(m.bytes.Bytes())
7171

7272
msg := session.messagePool.Get()
73-
if err := ParseMessage(msg, m.bytes); err != nil {
73+
if err := ParseMessageWithDataDictionary(msg, m.bytes, session.transportDataDictionary, session.appDataDictionary); err != nil {
7474
session.log.OnEventf("Msg Parse Error: %v, %q", err.Error(), m.bytes)
7575
} else {
7676
msg.ReceiveTime = m.receiveTime

0 commit comments

Comments
 (0)