forked from alpacahq/quickfix
-
Notifications
You must be signed in to change notification settings - Fork 1
/
message_build.go
98 lines (81 loc) · 2.83 KB
/
message_build.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package quickfix
import (
"errors"
"time"
)
// BuildMessageInput stores for building message data.
type BuildMessageInput struct {
Msg *Message
InReplyTo *Message
EnableLastMsgSeqNumProcessed bool
IsResetSeqNum bool
}
// BuildMessageOutput stores build message output data.
type BuildMessageOutput struct {
MsgBytes []byte
Msg *Message
SeqNum int
SentReset bool
}
// MsgSeqNumCursor interface provides methods for referencing/resetting the SeqNum position.
type MsgSeqNumCursor interface {
NextSenderMsgSeqNum() int
NextTargetMsgSeqNum() int
Reset() error
}
type messageBuilder struct {
cursor MsgSeqNumCursor
}
func newMessageBuilder(store MsgSeqNumCursor) *messageBuilder {
return &messageBuilder{store}
}
// BuildMessage ...
func (m *messageBuilder) BuildMessage(bd *BuildMessageInput) (output *BuildMessageOutput, err error) {
if m == nil || m.cursor == nil {
err = errors.New("failed to initialize. please to set cursor")
return
}
msg := bd.Msg
if bd.EnableLastMsgSeqNumProcessed {
if bd.InReplyTo != nil {
if lastSeqNum, err := bd.InReplyTo.Header.GetInt(tagMsgSeqNum); err == nil {
msg.Header.SetInt(tagLastMsgSeqNumProcessed, lastSeqNum)
}
} else {
msg.Header.SetInt(tagLastMsgSeqNumProcessed, m.cursor.NextTargetMsgSeqNum()-1)
}
}
outputData := BuildMessageOutput{}
outputData.SeqNum = m.cursor.NextSenderMsgSeqNum()
msg.Header.SetField(tagMsgSeqNum, FIXInt(outputData.SeqNum))
if bd.IsResetSeqNum { // for Logon message's ResetSeqNumFlag
if err = m.cursor.Reset(); err != nil {
return
}
outputData.SentReset = true
outputData.SeqNum = m.cursor.NextSenderMsgSeqNum()
msg.Header.SetField(tagMsgSeqNum, FIXInt(outputData.SeqNum))
}
outputData.MsgBytes = msg.build()
outputData.Msg = msg
output = &outputData
return
}
func insertSendingTime(msg *Message, sessionID SessionID, timestampPrecision TimestampPrecision) {
sendingTime := time.Now().UTC()
if sessionID.BeginString >= BeginStringFIX42 {
msg.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: sendingTime, Precision: timestampPrecision})
} else {
msg.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: sendingTime, Precision: Seconds})
}
}
func fillDefaultHeader(msg *Message, inReplyTo *Message, sessionID SessionID, timestampPrecision TimestampPrecision) {
msg.Header.SetString(tagBeginString, sessionID.BeginString)
msg.Header.SetString(tagSenderCompID, sessionID.SenderCompID)
optionallySetID(msg, tagSenderSubID, sessionID.SenderSubID)
optionallySetID(msg, tagSenderLocationID, sessionID.SenderLocationID)
msg.Header.SetString(tagTargetCompID, sessionID.TargetCompID)
optionallySetID(msg, tagTargetSubID, sessionID.TargetSubID)
optionallySetID(msg, tagTargetLocationID, sessionID.TargetLocationID)
insertSendingTime(msg, sessionID, timestampPrecision)
}