Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion in_session.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ func (state inSession) resendMessages(session *session, beginSeqNo, endSeqNo int
nextSeqNum := seqNum
msg := NewMessage()
for _, msgBytes := range msgs {
_ = ParseMessage(msg, bytes.NewBuffer(msgBytes))
_ = ParseMessageWithDataDictionary(msg, bytes.NewBuffer(msgBytes), session.transportDataDictionary, session.appDataDictionary)
msgType, _ := msg.Header.GetBytes(tagMsgType)
sentMessageSeqNum, _ := msg.Header.GetInt(tagMsgSeqNum)

Expand Down
42 changes: 40 additions & 2 deletions message.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"math"
"time"

"github.com/quickfixgo/quickfix/datadictionary"
"github.com/quickfixgo/quickfix/enum"
)

Expand Down Expand Up @@ -116,6 +117,16 @@ func NewMessage() *Message {

//ParseMessage constructs a Message from a byte slice wrapping a FIX message.
func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
return ParseMessageWithDataDictionary(msg, rawMessage, nil, nil)
}

//ParseMessageWithDataDictionary constructs a Message from a byte slice wrapping a FIX message using an optional session and application DataDictionary for reference.
func ParseMessageWithDataDictionary(
msg *Message,
rawMessage *bytes.Buffer,
transportDataDictionary *datadictionary.DataDictionary,
applicationDataDictionary *datadictionary.DataDictionary,
) (err error) {
msg.Header.Clear()
msg.Body.Clear()
msg.Trailer.Clear()
Expand Down Expand Up @@ -173,9 +184,9 @@ func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
}

switch {
case parsedFieldBytes.tag.IsHeader():
case isHeaderField(parsedFieldBytes.tag, transportDataDictionary):
msg.Header.add(msg.fields[fieldIndex : fieldIndex+1])
case parsedFieldBytes.tag.IsTrailer():
case isTrailerField(parsedFieldBytes.tag, transportDataDictionary):
msg.Trailer.add(msg.fields[fieldIndex : fieldIndex+1])
default:
foundBody = true
Expand Down Expand Up @@ -215,6 +226,33 @@ func ParseMessage(msg *Message, rawMessage *bytes.Buffer) (err error) {
}

return

}

func isHeaderField(tag Tag, dataDict *datadictionary.DataDictionary) bool {
if tag.IsHeader() {
return true
}

if dataDict == nil {
return false
}

_, ok := dataDict.Header.Fields[int(tag)]
return ok
}

func isTrailerField(tag Tag, dataDict *datadictionary.DataDictionary) bool {
if tag.IsTrailer() {
return true
}

if dataDict == nil {
return false
}

_, ok := dataDict.Trailer.Fields[int(tag)]
return ok
}

// MsgType returns MsgType (tag 35) field's value
Expand Down
23 changes: 22 additions & 1 deletion message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bytes"
"testing"

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

type MessageSuite struct {
suite.Suite
QuickFIXSuite
msg *Message
}

Expand Down Expand Up @@ -53,6 +54,26 @@ func (s *MessageSuite) TestParseMessage() {
s.False(s.msg.IsMsgTypeOf(enum.MsgType_LOGON))
}

func (s *MessageSuite) TestParseMessageWithDataDictionary() {
dict := new(datadictionary.DataDictionary)
dict.Header = &datadictionary.MessageDef{
Fields: map[int]*datadictionary.FieldDef{
10030: nil,
},
}
dict.Trailer = &datadictionary.MessageDef{
Fields: map[int]*datadictionary.FieldDef{
5050: nil,
},
}
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")

err := ParseMessageWithDataDictionary(s.msg, rawMsg, dict, dict)
s.Nil(err)
s.FieldEquals(Tag(10030), "CUST", s.msg.Header)
s.FieldEquals(Tag(5050), "HELLO", s.msg.Trailer)
}

func (s *MessageSuite) TestParseOutOfOrder() {
//allow fields out of order, save for validation
rawMsg := bytes.NewBufferString("8=FIX.4.09=8135=D11=id21=338=10040=154=155=MSFT34=249=TW52=20140521-22:07:0956=ISLD10=250")
Expand Down
3 changes: 3 additions & 0 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sync"
"time"

"github.com/quickfixgo/quickfix/datadictionary"
"github.com/quickfixgo/quickfix/enum"
"github.com/quickfixgo/quickfix/internal"
)
Expand Down Expand Up @@ -40,6 +41,8 @@ type session struct {

admin chan interface{}
internal.SessionSettings
transportDataDictionary *datadictionary.DataDictionary
appDataDictionary *datadictionary.DataDictionary

messagePool
}
Expand Down
12 changes: 5 additions & 7 deletions session_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,29 +97,27 @@ func (f sessionFactory) newSession(
return
}

var transportDataDictionary, appDataDictionary *datadictionary.DataDictionary
if transportDataDictionary, err = datadictionary.Parse(transportDataDictionaryPath); err != nil {
if s.transportDataDictionary, err = datadictionary.Parse(transportDataDictionaryPath); err != nil {
return
}

if appDataDictionary, err = datadictionary.Parse(appDataDictionaryPath); err != nil {
if s.appDataDictionary, err = datadictionary.Parse(appDataDictionaryPath); err != nil {
return
}

s.validator = &fixtValidator{transportDataDictionary, appDataDictionary, validatorSettings}
s.validator = &fixtValidator{s.transportDataDictionary, s.appDataDictionary, validatorSettings}
}
} else if settings.HasSetting(config.DataDictionary) {
var dataDictionaryPath string
if dataDictionaryPath, err = settings.Setting(config.DataDictionary); err != nil {
return
}

var dataDictionary *datadictionary.DataDictionary
if dataDictionary, err = datadictionary.Parse(dataDictionaryPath); err != nil {
if s.appDataDictionary, err = datadictionary.Parse(dataDictionaryPath); err != nil {
return
}

s.validator = &fixValidator{dataDictionary, validatorSettings}
s.validator = &fixValidator{s.appDataDictionary, validatorSettings}
}

if settings.HasSetting(config.ResetOnLogon) {
Expand Down
2 changes: 1 addition & 1 deletion session_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (sm *stateMachine) Incoming(session *session, m fixIn) {
session.log.OnIncoming(m.bytes.Bytes())

msg := session.messagePool.Get()
if err := ParseMessage(msg, m.bytes); err != nil {
if err := ParseMessageWithDataDictionary(msg, m.bytes, session.transportDataDictionary, session.appDataDictionary); err != nil {
session.log.OnEventf("Msg Parse Error: %v, %q", err.Error(), m.bytes)
} else {
msg.ReceiveTime = m.receiveTime
Expand Down