From 3ce26af1676c6f9a71449300a60d35581bf7c37e Mon Sep 17 00:00:00 2001 From: gpmn Date: Fri, 22 Feb 2019 19:36:01 +0800 Subject: [PATCH 001/178] in progress --- datadictionary/datadictionary.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/datadictionary/datadictionary.go b/datadictionary/datadictionary.go index 410ca8ee1..d051d4810 100644 --- a/datadictionary/datadictionary.go +++ b/datadictionary/datadictionary.go @@ -3,6 +3,7 @@ package datadictionary import ( "encoding/xml" + "io" "os" ) @@ -326,6 +327,9 @@ func Parse(path string) (*DataDictionary, error) { doc := new(XMLDoc) decoder := xml.NewDecoder(xmlFile) + decoder.CharsetReader = func(encoding string, input io.Reader) (io.Reader, error) { + return input, nil + } if err := decoder.Decode(doc); err != nil { return nil, err } From 07bfa3c02bd94cdc0d9a0f52876ddfd10fe1fd42 Mon Sep 17 00:00:00 2001 From: gpmn Date: Sat, 2 Mar 2019 00:53:36 +0800 Subject: [PATCH 002/178] https://github.com/quickfixgo/quickfix/issues/366 for Incorrect NumInGroup --- validation.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/validation.go b/validation.go index 6e28b8cd0..0c2167b56 100644 --- a/validation.go +++ b/validation.go @@ -10,15 +10,14 @@ type validator interface { type validatorSettings struct { CheckFieldsOutOfOrder bool - RejectInvalidMessage bool - + RejectInvalidMessage bool } //Default configuration for message validation. //See http://www.quickfixengine.org/quickfix/doc/html/configuration.html. var defaultValidatorSettings = validatorSettings{ CheckFieldsOutOfOrder: true, - RejectInvalidMessage: true, + RejectInvalidMessage: true, } type fixValidator struct { @@ -87,8 +86,6 @@ func validateFIX(d *datadictionary.DataDictionary, settings validatorSettings, m } } - - return nil } @@ -212,6 +209,7 @@ func validateVisitGroupField(fieldDef *datadictionary.FieldDef, fieldStack []Tag return fieldStack, err } } else { + fieldStack = fieldStack[1:] if childDefs[0].Required() { return fieldStack, RequiredTagMissing(Tag(childDefs[0].Tag())) } From dbd1cd31486be22bc1cae2b61ae85155e2410c28 Mon Sep 17 00:00:00 2001 From: gpmn Date: Sat, 2 Mar 2019 11:03:37 +0800 Subject: [PATCH 003/178] move down iteration operation --- validation.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation.go b/validation.go index 0c2167b56..7520d4b32 100644 --- a/validation.go +++ b/validation.go @@ -209,10 +209,10 @@ func validateVisitGroupField(fieldDef *datadictionary.FieldDef, fieldStack []Tag return fieldStack, err } } else { - fieldStack = fieldStack[1:] if childDefs[0].Required() { return fieldStack, RequiredTagMissing(Tag(childDefs[0].Tag())) } + fieldStack = fieldStack[1:] } childDefs = childDefs[1:] From fda6c290047878fc20a604e5b96c02ec7399df11 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Tue, 1 Feb 2022 20:57:24 +0100 Subject: [PATCH 004/178] Allow time.Duration or int for timeouts Signed-off-by: Sylvain Rabot --- dialer.go | 13 ++++++++++-- session_factory.go | 52 ++++++++++++++++++++++++++++------------------ 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/dialer.go b/dialer.go index 1645076bf..d89309c97 100644 --- a/dialer.go +++ b/dialer.go @@ -3,6 +3,7 @@ package quickfix import ( "fmt" "net" + "time" "github.com/quickfixgo/quickfix/config" "golang.org/x/net/proxy" @@ -11,8 +12,16 @@ import ( func loadDialerConfig(settings *SessionSettings) (dialer proxy.Dialer, err error) { stdDialer := &net.Dialer{} if settings.HasSetting(config.SocketTimeout) { - if stdDialer.Timeout, err = settings.DurationSetting(config.SocketTimeout); err != nil { - return + timeout, err := settings.DurationSetting(config.SocketTimeout) + if err != nil { + timeoutInt, err := settings.IntSetting(config.SocketTimeout) + if err != nil { + return stdDialer, err + } + + stdDialer.Timeout = time.Duration(timeoutInt) * time.Second + } else { + stdDialer.Timeout = timeout } } dialer = stdDialer diff --git a/session_factory.go b/session_factory.go index d119274cc..cfcbea4aa 100644 --- a/session_factory.go +++ b/session_factory.go @@ -321,47 +321,59 @@ func (f sessionFactory) buildInitiatorSettings(session *session, settings *Sessi session.ReconnectInterval = 30 * time.Second if settings.HasSetting(config.ReconnectInterval) { - - interval, err := settings.IntSetting(config.ReconnectInterval) + interval, err := settings.DurationSetting(config.ReconnectInterval) if err != nil { - return err + intervalInt, err := settings.IntSetting(config.ReconnectInterval) + if err != nil { + return err + } + + session.ReconnectInterval = time.Duration(intervalInt) * time.Second + } else { + session.ReconnectInterval = interval } - if interval <= 0 { + if session.ReconnectInterval <= 0 { return errors.New("ReconnectInterval must be greater than zero") } - - session.ReconnectInterval = time.Duration(interval) * time.Second } session.LogoutTimeout = 2 * time.Second if settings.HasSetting(config.LogoutTimeout) { - - timeout, err := settings.IntSetting(config.LogoutTimeout) + timeout, err := settings.DurationSetting(config.LogoutTimeout) if err != nil { - return err - } + timeoutInt, err := settings.IntSetting(config.LogoutTimeout) + if err != nil { + return err + } - if timeout <= 0 { - return errors.New("LogoutTimeout must be greater than zero") + session.LogoutTimeout = time.Duration(timeoutInt) * time.Second + } else { + session.LogoutTimeout = timeout } - session.LogoutTimeout = time.Duration(timeout) * time.Second + if session.LogoutTimeout <= 0 { + return errors.New("LogonTimeout must be greater than zero") + } } session.LogonTimeout = 10 * time.Second if settings.HasSetting(config.LogonTimeout) { - - timeout, err := settings.IntSetting(config.LogonTimeout) + timeout, err := settings.DurationSetting(config.LogonTimeout) if err != nil { - return err + timeoutInt, err := settings.IntSetting(config.LogonTimeout) + if err != nil { + return err + } + + session.LogonTimeout = time.Duration(timeoutInt) * time.Second + } else { + session.LogonTimeout = timeout } - if timeout <= 0 { + if session.LogonTimeout <= 0 { return errors.New("LogonTimeout must be greater than zero") } - - session.LogonTimeout = time.Duration(timeout) * time.Second } return f.configureSocketConnectAddress(session, settings) @@ -404,7 +416,7 @@ func (f sessionFactory) buildHeartBtIntSettings(session *session, settings *Sess return } } - + if session.HeartBtIntOverride || mustProvide { var heartBtInt int if heartBtInt, err = settings.IntSetting(config.HeartBtInt); err != nil { From ede50142b238a62b4c2fa34209a6c3158315c0b4 Mon Sep 17 00:00:00 2001 From: zee276 Date: Thu, 14 Apr 2022 12:47:49 +0200 Subject: [PATCH 005/178] add session reset --- registry.go | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/registry.go b/registry.go index 3c1fb2af8..759b3115f 100644 --- a/registry.go +++ b/registry.go @@ -50,6 +50,21 @@ func SendToTarget(m Messagable, sessionID SessionID) error { return session.queueForSend(msg) } +//ResetSession resets session's sequence numbers +func ResetSession(sessionID SessionID) error { + session, ok := lookupSession(sessionID) + if !ok { + return errUnknownSession + } + session.log.OnEvent("Session reset") + session.State.ShutdownNow(session) + if err := session.dropAndReset(); err != nil { + session.logError(err) + } + + return nil +} + //UnregisterSession removes a session from the set of known sessions func UnregisterSession(sessionID SessionID) error { sessionsLock.Lock() From e6c717d4f5a329fb4a53f2020328aeb9961f4b57 Mon Sep 17 00:00:00 2001 From: zee276 Date: Thu, 14 Apr 2022 12:53:17 +0200 Subject: [PATCH 006/178] add session reset --- registry.go | 1 + 1 file changed, 1 insertion(+) diff --git a/registry.go b/registry.go index 759b3115f..dd1c7b26f 100644 --- a/registry.go +++ b/registry.go @@ -60,6 +60,7 @@ func ResetSession(sessionID SessionID) error { session.State.ShutdownNow(session) if err := session.dropAndReset(); err != nil { session.logError(err) + return err } return nil From 4409144088a332f3f10594fb4eeb8fbab826a99f Mon Sep 17 00:00:00 2001 From: Sam Mulube Date: Tue, 30 Aug 2022 11:35:05 +0100 Subject: [PATCH 007/178] Add Weekdays configuration option to sessions Update TimeRange to include weekdays - add weekdays slice as field to TimeRange - update constructor to remove possible panic, instead return error - update tests now the TimeRange constructor now returns an error - convert tests to table test format Update sessionFactory to set weekdays property - update code that creates TimeRange to handle errors - read and set the Weekdays value if provided, erroring if it is given with StartDay/EndDay. Update session_test to handle timerange error --- config/configuration.go | 3 +- config/doc.go | 10 +- internal/time_range.go | 43 +- internal/time_range_test.go | 1257 +++++++++++++++++++++++++---------- session_factory.go | 41 +- session_factory_test.go | 109 ++- session_test.go | 36 +- 7 files changed, 1130 insertions(+), 369 deletions(-) diff --git a/config/configuration.go b/config/configuration.go index ed7f1303e..d5ae023b2 100644 --- a/config/configuration.go +++ b/config/configuration.go @@ -2,7 +2,7 @@ package config //NOTE: Additions to this file should be made to both config/doc.go and http://www.quickfixgo.org/docs/ -//Const configuration settings +// Const configuration settings const ( BeginString string = "BeginString" SenderCompID string = "SenderCompID" @@ -35,6 +35,7 @@ const ( EndTime string = "EndTime" StartDay string = "StartDay" EndDay string = "EndDay" + Weekdays string = "Weekdays" TimeZone string = "TimeZone" DataDictionary string = "DataDictionary" TransportDataDictionary string = "TransportDataDictionary" diff --git a/config/doc.go b/config/doc.go index c7223bbad..ed9952fd2 100644 --- a/config/doc.go +++ b/config/doc.go @@ -84,16 +84,22 @@ Time of day that this FIX session becomes deactivated. Valid Values: StartDay -For week long sessions, the starting day of week for the session. Use in combination with StartTime. Valid Values: +For week long sessions, the starting day of week for the session. Use in combination with StartTime. Incompatible with Weekdays. Valid Values: Full day of week in English, or 3 letter abbreviation (i.e. Monday and Mon are valid) EndDay -For week long sessions, the ending day of week for the session. Use in combination with EndTime. Valid Values: +For week long sessions, the ending day of week for the session. Use in combination with EndTime. Incompatible with Weekdays. Valid Values: Full day of week in English, or 3 letter abbreviation (i.e. Monday and Mon are valid) +Weekdays + +For daily sessions that are only active on specific days of the week. Use in combination with StartTime and EndTime. Incompatible with StartDay and EndDay. Valid Values: + + Comma delimited list of days of the week in English, or 3 letter abbreviation (e.g. "Monday,Tuesday,Wednesday" or "Mon,Tue,Wed" would both be valid values) + EnableLastMsgSeqNumProcessed Add the last message sequence number processed in the header (optional tag 369). Valid Values: diff --git a/internal/time_range.go b/internal/time_range.go index e69f2fd21..eea0141b4 100644 --- a/internal/time_range.go +++ b/internal/time_range.go @@ -36,42 +36,65 @@ func ParseTimeOfDay(str string) (TimeOfDay, error) { //TimeRange represents a time band in a given time zone type TimeRange struct { startTime, endTime TimeOfDay + weekdays []time.Weekday startDay, endDay *time.Weekday loc *time.Location } //NewUTCTimeRange returns a time range in UTC -func NewUTCTimeRange(start, end TimeOfDay) *TimeRange { - return NewTimeRangeInLocation(start, end, time.UTC) +func NewUTCTimeRange(start, end TimeOfDay, weekdays []time.Weekday) (*TimeRange, error) { + return NewTimeRangeInLocation(start, end, weekdays, time.UTC) } //NewTimeRangeInLocation returns a time range in a given location -func NewTimeRangeInLocation(start, end TimeOfDay, loc *time.Location) *TimeRange { +func NewTimeRangeInLocation(start, end TimeOfDay, weekdays []time.Weekday, loc *time.Location) (*TimeRange, error) { if loc == nil { - panic("time: missing Location in call to NewTimeRangeInLocation") + return nil, errors.New("time: missing Location in call to NewTimeRangeInLocation") } - return &TimeRange{startTime: start, endTime: end, loc: loc} + return &TimeRange{ + startTime: start, + endTime: end, + weekdays: weekdays, + loc: loc, + }, nil } //NewUTCWeekRange returns a weekly TimeRange -func NewUTCWeekRange(startTime, endTime TimeOfDay, startDay, endDay time.Weekday) *TimeRange { +func NewUTCWeekRange(startTime, endTime TimeOfDay, startDay, endDay time.Weekday) (*TimeRange, error) { return NewWeekRangeInLocation(startTime, endTime, startDay, endDay, time.UTC) } -//NewWeekRangeInLocation returns a time range in a given location -func NewWeekRangeInLocation(startTime, endTime TimeOfDay, startDay, endDay time.Weekday, loc *time.Location) *TimeRange { - r := NewTimeRangeInLocation(startTime, endTime, loc) +func NewWeekRangeInLocation(startTime, endTime TimeOfDay, startDay, endDay time.Weekday, loc *time.Location) (*TimeRange, error) { + r, err := NewTimeRangeInLocation(startTime, endTime, []time.Weekday{}, loc) + if err != nil { + return nil, err + } r.startDay = &startDay r.endDay = &endDay - return r + return r, nil } func (r *TimeRange) isInTimeRange(t time.Time) bool { t = t.In(r.loc) ts := NewTimeOfDay(t.Clock()).d + if len(r.weekdays) > 0 { + found := false + + for _, weekday := range r.weekdays { + if t.Weekday() == weekday { + found = true + break + } + } + + if !found { + return false + } + } + if r.startTime.d < r.endTime.d { return r.startTime.d <= ts && ts <= r.endTime.d } diff --git a/internal/time_range_test.go b/internal/time_range_test.go index a28a495f5..55740b113 100644 --- a/internal/time_range_test.go +++ b/internal/time_range_test.go @@ -31,49 +31,68 @@ func TestParseTime(t *testing.T) { } func TestNewUTCTimeRange(t *testing.T) { - r := NewUTCTimeRange(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0)) + r, err := NewUTCTimeRange(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), []time.Weekday{}) + assert.Nil(t, err) assert.Equal(t, NewTimeOfDay(3, 0, 0), r.startTime) assert.Equal(t, NewTimeOfDay(18, 0, 0), r.endTime) + assert.Equal(t, []time.Weekday{}, r.weekdays) assert.Nil(t, r.startDay) assert.Nil(t, r.endDay) assert.Equal(t, time.UTC, r.loc) } func TestNewTimeRangeInLocation(t *testing.T) { - r := NewTimeRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Local) + r, err := NewTimeRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), []time.Weekday{}, time.Local) + assert.Nil(t, err) assert.Equal(t, NewTimeOfDay(3, 0, 0), r.startTime) assert.Equal(t, NewTimeOfDay(18, 0, 0), r.endTime) + assert.Equal(t, []time.Weekday{}, r.weekdays) assert.Nil(t, r.startDay) assert.Nil(t, r.endDay) assert.Equal(t, time.Local, r.loc) } +func TestNewTimeRangeInNilLocation(t *testing.T) { + _, err := NewTimeRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), []time.Weekday{}, nil) + assert.EqualError(t, err, "time: missing Location in call to NewTimeRangeInLocation") +} + func TestNewUTCWeekRange(t *testing.T) { - r := NewUTCWeekRange(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Monday, time.Wednesday) + r, err := NewUTCWeekRange(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Monday, time.Wednesday) + assert.Nil(t, err) assert.Equal(t, NewTimeOfDay(3, 0, 0), r.startTime) assert.Equal(t, NewTimeOfDay(18, 0, 0), r.endTime) assert.NotNil(t, r.startDay) assert.NotNil(t, r.endDay) + assert.Equal(t, []time.Weekday{}, r.weekdays) assert.Equal(t, time.Monday, *r.startDay) assert.Equal(t, time.Wednesday, *r.endDay) assert.Equal(t, time.UTC, r.loc) } func TestNewWeekRangeInLocation(t *testing.T) { - r := NewWeekRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Monday, time.Wednesday, time.Local) + r, err := NewWeekRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Monday, time.Wednesday, time.Local) + assert.Nil(t, err) assert.Equal(t, NewTimeOfDay(3, 0, 0), r.startTime) assert.Equal(t, NewTimeOfDay(18, 0, 0), r.endTime) assert.NotNil(t, r.startDay) assert.NotNil(t, r.endDay) + assert.Equal(t, []time.Weekday{}, r.weekdays) assert.Equal(t, time.Monday, *r.startDay) assert.Equal(t, time.Wednesday, *r.endDay) assert.Equal(t, time.Local, r.loc) } +func TestNewWeekRangeInNilLocation(t *testing.T) { + _, err := NewWeekRangeInLocation(NewTimeOfDay(3, 0, 0), NewTimeOfDay(18, 0, 0), time.Monday, time.Wednesday, nil) + assert.EqualError(t, err, "time: missing Location in call to NewTimeRangeInLocation") +} + func BenchmarkInRange(b *testing.B) { start := NewTimeOfDay(3, 0, 0) end := NewTimeOfDay(18, 0, 0) - tr := NewUTCTimeRange(start, end) + weekdays := []time.Weekday{} + tr, _ := NewUTCTimeRange(start, end, weekdays) now := time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) for n := 0; n < b.N; n++ { @@ -82,355 +101,919 @@ func BenchmarkInRange(b *testing.B) { } func TestTimeRangeIsInRange(t *testing.T) { - start := NewTimeOfDay(3, 0, 0) - end := NewTimeOfDay(18, 0, 0) - - now := time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - assert.True(t, NewUTCTimeRange(start, end).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC) - assert.True(t, NewUTCTimeRange(start, end).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 18, 0, 1, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInRange(now)) - - start = NewTimeOfDay(18, 0, 0) - end = NewTimeOfDay(3, 0, 0) - now = time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC) - assert.True(t, NewUTCTimeRange(start, end).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 3, 0, 0, 0, time.UTC) - assert.True(t, NewUTCTimeRange(start, end).IsInRange(now)) + testcases := []struct { + label string + start TimeOfDay + end TimeOfDay + weekdays []time.Weekday + location *time.Location + now time.Time + expectedInRange bool + }{ + { + label: "10AM", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "6PM", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "2AM", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "7PM", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "6:01PM", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 18, 1, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "6PM, inverted start/end", + start: NewTimeOfDay(18, 0, 0), + end: NewTimeOfDay(3, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "3AM, inverted start/end", + start: NewTimeOfDay(18, 0, 0), + end: NewTimeOfDay(3, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 3, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "4AM, inverted start/end", + start: NewTimeOfDay(18, 0, 0), + end: NewTimeOfDay(3, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 4, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "5PM, inverted start/end", + start: NewTimeOfDay(18, 0, 0), + end: NewTimeOfDay(3, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 17, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "3AM in fixed zone of -60", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(5, 0, 0), + weekdays: []time.Weekday{}, + location: time.FixedZone("myzone", -60), + now: time.Date(2016, time.August, 10, 3, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "3:01AM in fixed zone of -60", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(5, 0, 0), + weekdays: []time.Weekday{}, + location: time.FixedZone("myzone", -60), + now: time.Date(2016, time.August, 10, 3, 1, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "equal start/end", + start: NewTimeOfDay(0, 0, 0), + end: NewTimeOfDay(0, 0, 0), + weekdays: []time.Weekday{}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "10AM, weekdays in range", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday, time.Thursday}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "10AM, weekdays out of range", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{time.Monday, time.Tuesday}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "2AM, weekdays in range", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + weekdays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday}, + location: time.UTC, + now: time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + } - now = time.Date(2016, time.August, 10, 4, 0, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInRange(now)) + for _, tc := range testcases { + t.Run(tc.label, func(t *testing.T) { + timeRange, err := NewTimeRangeInLocation(tc.start, tc.end, tc.weekdays, tc.location) + assert.Nil(t, err) + assert.Equal(t, tc.expectedInRange, timeRange.IsInRange(tc.now)) + }) + } +} - now = time.Date(2016, time.August, 10, 17, 0, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInRange(now)) +func TestTimeInRangeNil(t *testing.T) { + now := time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC) var tr *TimeRange - assert.True(t, tr.IsInRange(now), "always in range if time range is nil") - - loc := time.FixedZone("myzone", -60) - start = NewTimeOfDay(3, 0, 0) - end = NewTimeOfDay(5, 0, 0) - - now = time.Date(2016, time.August, 10, 3, 0, 0, 0, time.UTC) - assert.False(t, NewTimeRangeInLocation(start, end, loc).IsInRange(now)) - - now = time.Date(2016, time.August, 10, 3, 1, 0, 0, time.UTC) - assert.True(t, NewTimeRangeInLocation(start, end, loc).IsInRange(now)) - - start = NewTimeOfDay(0, 0, 0) - end = NewTimeOfDay(0, 0, 0) - now = time.Date(2016, time.August, 10, 18, 0, 0, 0, time.UTC) - assert.True(t, NewUTCTimeRange(start, end).IsInRange(now)) - + assert.True(t, tr.IsInRange(now), "always in range if the time range is nil") } func TestTimeRangeIsInRangeWithDay(t *testing.T) { + testcases := []struct { + label string + startTime TimeOfDay + endTime TimeOfDay + startDay time.Weekday + endDay time.Weekday + weekdays []time.Weekday + location *time.Location + now time.Time + expectedInRange bool + }{ + { + label: "2AM Wednesday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 28, 2, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "6PM Tuesday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 27, 18, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "10PM Tuesday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 27, 22, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "3AM Tuesday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "2:59:59 Monday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 26, 2, 59, 59, 0, time.UTC), + expectedInRange: false, + }, + { + label: "6:01PM Thursday", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + now: time.Date(2004, time.July, 29, 18, 0, 1, 0, time.UTC), + expectedInRange: false, + }, + { + label: "2AM Saturday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 24, 2, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "2AM Wednesday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 28, 2, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "3AM Thursday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 22, 3, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "6PM Monday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 26, 18, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "2:59AM Thursday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 22, 2, 59, 59, 0, time.UTC), + expectedInRange: false, + }, + { + label: "6:01PM Monday, inverted days", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Thursday, + endDay: time.Monday, + location: time.UTC, + now: time.Date(2004, time.July, 26, 18, 0, 1, 0, time.UTC), + expectedInRange: false, + }, + { + label: "8:59AM Sunday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 8, 59, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "8:59:01AM Sunday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 8, 59, 1, 0, time.UTC), + expectedInRange: false, + }, + { + label: "9:01AM Sunday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "9AM Sunday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 9, 0, 0, 0, time.UTC), + expectedInRange: false, + }, + { + label: "8:59AM Monday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 4, 8, 59, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "8:59:01AM Monday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 4, 8, 59, 1, 0, time.UTC), + expectedInRange: true, + }, + { + label: "9:01AM Monday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 4, 9, 1, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "9AM Monday, whole week", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 4, 9, 0, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "8:59AM Sunday, whole week, inverted times", + startTime: NewTimeOfDay(8, 59, 0), + endTime: NewTimeOfDay(9, 1, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 8, 59, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "9:01AM Sunday, whole week, inverted times", + startTime: NewTimeOfDay(8, 59, 0), + endTime: NewTimeOfDay(9, 1, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + expectedInRange: true, + }, + { + label: "8:59AM Monday, whole week, inverted times", + startTime: NewTimeOfDay(8, 59, 0), + endTime: NewTimeOfDay(9, 1, 0), + startDay: time.Sunday, + endDay: time.Sunday, + location: time.UTC, + now: time.Date(2006, time.December, 4, 8, 59, 0, 0, time.UTC), + expectedInRange: false, + }, + } - startTime := NewTimeOfDay(3, 0, 0) - endTime := NewTimeOfDay(18, 0, 0) - startDay := time.Monday - endDay := time.Thursday - - now := time.Date(2004, time.July, 28, 2, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 27, 18, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 26, 2, 59, 59, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 29, 18, 0, 1, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - startDay = time.Thursday - endDay = time.Monday - - now = time.Date(2004, time.July, 24, 2, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 28, 2, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 22, 3, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 26, 18, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 22, 2, 59, 59, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2004, time.July, 26, 18, 0, 1, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - startTime = NewTimeOfDay(9, 1, 0) - endTime = NewTimeOfDay(8, 59, 0) - startDay = time.Sunday - endDay = time.Sunday - - now = time.Date(2006, time.December, 3, 8, 59, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 3, 8, 59, 1, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - now = time.Date(2006, time.December, 3, 9, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 4, 8, 59, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 4, 8, 59, 1, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 4, 9, 1, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 4, 9, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - startTime = NewTimeOfDay(8, 59, 0) - endTime = NewTimeOfDay(9, 1, 0) - startDay = time.Sunday - endDay = time.Sunday - - now = time.Date(2006, time.December, 3, 8, 59, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) - - now = time.Date(2006, time.December, 4, 8, 59, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInRange(now)) + for _, tc := range testcases { + t.Run(tc.label, func(t *testing.T) { + timeRange, err := NewWeekRangeInLocation(tc.startTime, tc.endTime, tc.startDay, tc.endDay, tc.location) + assert.Nil(t, err) + assert.Equal(t, tc.expectedInRange, timeRange.IsInRange(tc.now)) + }) + } } func TestTimeRangeIsInSameRange(t *testing.T) { + testcases := []struct { + label string + start TimeOfDay + end TimeOfDay + location *time.Location + weekdays []time.Weekday + examples []struct { + label string + time1 time.Time + time2 time.Time + expected bool + } + }{ + { + label: "start time is less than end time", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same time", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time2 in same session but greater", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time2 in same session but less", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time1 not in same session", + time1: time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expected: false, + }, + { + label: "time2 not in same session", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC), + expected: false, + }, + { + label: "time1 within time range but next day", + time1: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expected: false, + }, + { + label: "time2 within time range but next day", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "with weekdays, start time is less than end time", + start: NewTimeOfDay(3, 0, 0), + end: NewTimeOfDay(18, 0, 0), + location: time.UTC, + weekdays: []time.Weekday{time.Monday, time.Tuesday, time.Wednesday}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same time within range", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "same time outside weekdays range", + time1: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + expected: false, + }, + { + label: "time2 in same session but greater within range", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time2 in same session but less within range", + time1: time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time2 in same session but greater outside range", + time1: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 11, 0, 0, 0, time.UTC), + expected: false, + }, + { + label: "time2 in same session but less outside range", + time1: time.Date(2016, time.August, 11, 10, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 11, 0, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "start time is greater than end time", + start: NewTimeOfDay(18, 0, 0), + end: NewTimeOfDay(3, 0, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same session, same day", + time1: time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 20, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "same session, time2 is in next day", + time1: time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 2, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "same session, time1 is in next day", + time1: time.Date(2016, time.August, 11, 2, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "time1 is 25 hours greater than time2", + time1: time.Date(2016, time.August, 11, 21, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 20, 0, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "start time is equal to end time", + start: NewTimeOfDay(6, 0, 0), + end: NewTimeOfDay(6, 0, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "times on different days", + time1: time.Date(2016, time.January, 13, 19, 10, 0, 0, time.UTC), + time2: time.Date(2016, time.January, 14, 19, 6, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "in different time zone", + start: NewTimeOfDay(0, 0, 0), + end: NewTimeOfDay(2, 0, 0), + location: time.FixedZone("myzone", -60), + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same times in range", + time1: time.Date(2016, time.August, 10, 0, 1, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 0, 1, 0, 0, time.UTC), + expected: true, + }, + }, + }, + { + label: "in different time zone, inverted start/end", + start: NewTimeOfDay(2, 0, 0), + end: NewTimeOfDay(0, 0, 0), + location: time.FixedZone("myzone", -60), + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same times in range", + time1: time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC), + expected: true, + }, + }, + }, + { + label: "midnight to midnight session in time zone", + start: NewTimeOfDay(0, 0, 0), + end: NewTimeOfDay(0, 0, 0), + location: time.FixedZone("custom", -60), + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "different days UTC but same in fixed zone", + time1: time.Date(2016, time.August, 10, 0, 0, 0, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 0, 0, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "midnight to midnight session in UTC", + start: NewTimeOfDay(0, 0, 0), + end: NewTimeOfDay(0, 0, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "spanning midnight", + time1: time.Date(2016, time.August, 10, 23, 59, 59, 0, time.UTC), + time2: time.Date(2016, time.August, 11, 0, 0, 0, 0, time.UTC), + expected: false, + }, + }, + }, + { + label: "1:49 to 1:49 session", + start: NewTimeOfDay(1, 49, 0), + end: NewTimeOfDay(1, 49, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "edgecase 1", + time1: time.Date(2016, time.August, 16, 1, 48, 21, 0, time.UTC), + time2: time.Date(2016, time.August, 16, 1, 49, 02, 0, time.UTC), + expected: false, + }, + { + label: "edgecase 2", + time1: time.Date(2016, time.August, 16, 13, 48, 21, 0, time.UTC), + time2: time.Date(2016, time.August, 16, 13, 49, 02, 0, time.UTC), + expected: true, + }, + }, + }, + { + label: "13:49 to 13:49 session", + start: NewTimeOfDay(13, 49, 0), + end: NewTimeOfDay(13, 49, 0), + location: time.UTC, + weekdays: []time.Weekday{}, + examples: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "edgecase 1", + time1: time.Date(2016, time.August, 16, 13, 48, 21, 0, time.UTC), + time2: time.Date(2016, time.August, 16, 13, 49, 02, 0, time.UTC), + expected: false, + }, + }, + }, + } - // start time is less than end time - start := NewTimeOfDay(3, 0, 0) - end := NewTimeOfDay(18, 0, 0) - - // same time - time1 := time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - time2 := time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - // time 2 in same session but greater - time1 = time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // time 2 in same session but less - time1 = time.Date(2016, time.August, 10, 11, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // time 1 not in session - time1 = time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // time 2 not in session - time1 = time.Date(2016, time.August, 10, 10, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 2, 0, 0, 0, time.UTC) - - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // start time is greater than end time - start = NewTimeOfDay(18, 0, 0) - end = NewTimeOfDay(3, 0, 0) - - // same session same day - time1 = time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 20, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // same session time 2 is in next day - time1 = time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 11, 2, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // same session time 1 is in next day - time1 = time.Date(2016, time.August, 11, 2, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 19, 0, 0, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // time 1 is 25 hours greater (han time 2 - time1 = time.Date(2016, time.August, 11, 21, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 20, 0, 0, 0, time.UTC) - - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - // start time is greater than end time - start = NewTimeOfDay(6, 0, 0) - end = NewTimeOfDay(6, 0, 0) + for _, tc := range testcases { + t.Run(tc.label, func(t *testing.T) { + var timeRange *TimeRange + var err error + + if tc.location == time.UTC { + timeRange, err = NewUTCTimeRange(tc.start, tc.end, tc.weekdays) + } else { + timeRange, err = NewTimeRangeInLocation(tc.start, tc.end, tc.weekdays, tc.location) + } + assert.Nil(t, err) + + for _, example := range tc.examples { + t.Run(example.label, func(t *testing.T) { + assert.Equal(t, example.expected, timeRange.IsInSameRange(example.time1, example.time2)) + assert.Equal(t, example.expected, timeRange.IsInSameRange(example.time2, example.time1)) + }) + } + }) + } - time1 = time.Date(2016, time.January, 13, 19, 10, 0, 0, time.UTC) - time2 = time.Date(2016, time.January, 14, 19, 6, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) +} - start = NewTimeOfDay(0, 0, 0) - end = NewTimeOfDay(2, 0, 0) - loc := time.FixedZone("myzone", -60) +func TestTimeRangeIsInSameRangeWithDay(t *testing.T) { + testcases := []struct { + label string + startTime TimeOfDay + endTime TimeOfDay + startDay time.Weekday + endDay time.Weekday + location *time.Location + cases []struct { + label string + time1 time.Time + time2 time.Time + expected bool + } + }{ + { + label: "base example", + startTime: NewTimeOfDay(3, 0, 0), + endTime: NewTimeOfDay(18, 0, 0), + startDay: time.Monday, + endDay: time.Thursday, + location: time.UTC, + cases: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "time1 before day range", + time1: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), // Tuesday + time2: time.Date(2004, time.July, 25, 3, 0, 0, 0, time.UTC), // Sunday + expected: false, + }, + { + label: "time1 after day range", + time1: time.Date(2004, time.July, 31, 3, 0, 0, 0, time.UTC), // Saturday + time2: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), // Tuesday + expected: false, + }, + { + label: "same date/time", + time1: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), // Tuesday + time2: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), // Tuesday + expected: true, + }, + { + label: "different days within day range", + time1: time.Date(2004, time.July, 26, 10, 0, 0, 0, time.UTC), // Monday + time2: time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC), // Tuesday + expected: true, + }, + { + label: "different days within day range 2", + time1: time.Date(2004, time.July, 27, 10, 0, 0, 0, time.UTC), // Tuesday + time2: time.Date(2004, time.July, 29, 2, 0, 0, 0, time.UTC), // Thursday + expected: true, + }, + { + label: "same day, different weeks", + time1: time.Date(2004, time.July, 27, 10, 0, 0, 0, time.UTC), // Tuesday + time2: time.Date(2004, time.July, 20, 3, 0, 0, 0, time.UTC), // Tuesday + expected: false, + }, + { + label: "same day, different weeks inverted", + time1: time.Date(2004, time.July, 20, 3, 0, 0, 0, time.UTC), // Tuesday + time2: time.Date(2004, time.July, 27, 10, 0, 0, 0, time.UTC), // Tuesday + expected: false, + }, + { + label: "different weeks again", + time1: time.Date(2004, time.July, 26, 2, 0, 0, 0, time.UTC), // Monday + time2: time.Date(2004, time.July, 19, 3, 0, 0, 0, time.UTC), // Monday + expected: false, + }, + }, + }, + { + label: "start/end time within an hour of midnight, week long session", + startTime: NewTimeOfDay(0, 5, 0), + endTime: NewTimeOfDay(23, 45, 0), + startDay: time.Sunday, + endDay: time.Saturday, + location: time.UTC, + cases: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "check DST change is handled when missing an hour", + time1: time.Date(2006, time.April, 4, 0, 0, 0, 0, time.UTC), + time2: time.Date(2006, time.April, 3, 1, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "check DST change is handled when gaining an hour", + time1: time.Date(2006, time.October, 30, 0, 0, 0, 0, time.UTC), + time2: time.Date(2006, time.October, 31, 1, 0, 0, 0, time.UTC), + expected: true, + }, + { + label: "works across year boundary", + time1: time.Date(2006, time.December, 31, 10, 10, 10, 0, time.UTC), + time2: time.Date(2007, time.January, 1, 10, 10, 10, 0, time.UTC), + expected: true, + }, + }, + }, + { + label: "when session days are the same", + startTime: NewTimeOfDay(9, 1, 0), + endTime: NewTimeOfDay(8, 59, 0), + location: time.UTC, + cases: []struct { + label string + time1 time.Time + time2 time.Time + expected bool + }{ + { + label: "same time", + time1: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + time2: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + expected: true, + }, + { + label: "different week", + time1: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + time2: time.Date(2006, time.December, 10, 9, 1, 0, 0, time.UTC), + expected: false, + }, + { + label: "different day", + time1: time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC), + time2: time.Date(2006, time.December, 4, 9, 1, 0, 0, time.UTC), + expected: true, + }, + }, + }, + } - time1 = time.Date(2016, time.August, 10, 0, 1, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 0, 1, 0, 0, time.UTC) - assert.True(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time1, time2)) - assert.True(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time2, time1)) + for _, tc := range testcases { + t.Run(tc.label, func(t *testing.T) { + var timeRange *TimeRange + var err error + + if tc.location == time.UTC { + timeRange, err = NewUTCWeekRange(tc.startTime, tc.endTime, tc.startDay, tc.endDay) + } else { + timeRange, err = NewWeekRangeInLocation(tc.startTime, tc.endTime, tc.startDay, tc.endDay, tc.location) + } + assert.Nil(t, err) + + for _, c := range tc.cases { + t.Run(c.label, func(t *testing.T) { + assert.Equal(t, c.expected, timeRange.IsInSameRange(c.time1, c.time2)) + }) + } + }) + } +} - start = NewTimeOfDay(2, 0, 0) - end = NewTimeOfDay(0, 0, 0) - time1 = time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC) - assert.True(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time1, time2)) - assert.True(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time2, time1)) +func TestTimeRangeIsInSameRangeWhenNil(t *testing.T) { + time1 := time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC) + time2 := time.Date(2016, time.August, 10, 2, 1, 0, 0, time.UTC) var tr *TimeRange assert.True(t, tr.IsInSameRange(time1, time2), "always in same range if time range is nil") - - start = NewTimeOfDay(0, 0, 0) - end = NewTimeOfDay(0, 0, 0) - time1 = time.Date(2016, time.August, 10, 0, 0, 0, 0, time.UTC) - time2 = time.Date(2016, time.August, 11, 0, 0, 0, 0, time.UTC) - assert.False(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time1, time2)) - assert.False(t, NewTimeRangeInLocation(start, end, loc).IsInSameRange(time2, time1)) - - time1 = time.Date(2016, time.August, 10, 23, 59, 59, 0, time.UTC) - time2 = time.Date(2016, time.August, 11, 0, 0, 0, 0, time.UTC) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - start = NewTimeOfDay(1, 49, 0) - end = NewTimeOfDay(1, 49, 0) - time1 = time.Date(2016, time.August, 16, 1, 48, 21, 0, time.UTC) - time2 = time.Date(2016, time.August, 16, 1, 49, 02, 0, time.UTC) - - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - start = NewTimeOfDay(1, 49, 0) - end = NewTimeOfDay(1, 49, 0) - time1 = time.Date(2016, time.August, 16, 13, 48, 21, 0, time.UTC) - time2 = time.Date(2016, time.August, 16, 13, 49, 02, 0, time.UTC) - - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.True(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) - - start = NewTimeOfDay(13, 49, 0) - end = NewTimeOfDay(13, 49, 0) - time1 = time.Date(2016, time.August, 16, 13, 48, 21, 0, time.UTC) - time2 = time.Date(2016, time.August, 16, 13, 49, 02, 0, time.UTC) - - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time1, time2)) - assert.False(t, NewUTCTimeRange(start, end).IsInSameRange(time2, time1)) -} - -func TestTimeRangeIsInSameRangeWithDay(t *testing.T) { - - startTime := NewTimeOfDay(3, 0, 0) - endTime := NewTimeOfDay(18, 0, 0) - startDay := time.Monday - endDay := time.Thursday - - time1 := time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - time2 := time.Date(2004, time.July, 25, 3, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 31, 3, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 26, 10, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 27, 3, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 27, 10, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 29, 2, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 27, 10, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 20, 3, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 27, 2, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 20, 3, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time1 = time.Date(2004, time.July, 26, 2, 0, 0, 0, time.UTC) - time2 = time.Date(2004, time.July, 19, 3, 0, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - // Reset start/end time so that they fall within an hour of midnight - startTime = NewTimeOfDay(0, 5, 0) - endTime = NewTimeOfDay(23, 45, 0) - - // Make it a week-long session - startDay = time.Sunday - endDay = time.Saturday - - // Check that ST-->DST (Sunday is missing one hour) is handled - time1 = time.Date(2006, time.April, 4, 0, 0, 0, 0, time.UTC) - time2 = time.Date(2006, time.April, 3, 1, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - // Check that DST-->ST (Sunday has an extra hour) is handled - time1 = time.Date(2006, time.October, 30, 0, 0, 0, 0, time.UTC) - time2 = time.Date(2006, time.October, 31, 1, 0, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - // Check that everything works across a year boundary - time1 = time.Date(2006, time.December, 31, 10, 10, 10, 0, time.UTC) - time2 = time.Date(2007, time.January, 1, 10, 10, 10, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - // Session days are the same - startDay = time.Sunday - endDay = time.Sunday - startTime = NewTimeOfDay(9, 1, 0) - endTime = NewTimeOfDay(8, 59, 0) - time1 = time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC) - time2 = time.Date(2006, time.December, 3, 9, 1, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time2 = time.Date(2006, time.December, 10, 9, 1, 0, 0, time.UTC) - assert.False(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) - - time2 = time.Date(2006, time.December, 4, 9, 1, 0, 0, time.UTC) - assert.True(t, NewUTCWeekRange(startTime, endTime, startDay, endDay).IsInSameRange(time1, time2)) } diff --git a/session_factory.go b/session_factory.go index 8fc42d3c0..5afebbe30 100644 --- a/session_factory.go +++ b/session_factory.go @@ -3,6 +3,7 @@ package quickfix import ( "net" "strconv" + "strings" "time" "github.com/pkg/errors" @@ -46,7 +47,7 @@ type sessionFactory struct { BuildInitiators bool } -//Creates Session, associates with internal session registry +// Creates Session, associates with internal session registry func (f sessionFactory) createSession( sessionID SessionID, storeFactory MessageStoreFactory, settings *SessionSettings, logFactory LogFactory, application Application, @@ -244,8 +245,37 @@ func (f sessionFactory) newSession( } if !settings.HasSetting(config.StartDay) && !settings.HasSetting(config.EndDay) { - s.SessionTime = internal.NewTimeRangeInLocation(start, end, loc) + weekdays := []time.Weekday{} + if settings.HasSetting(config.Weekdays) { + var weekdaysStr string + if weekdaysStr, err = settings.Setting(config.Weekdays); err != nil { + return + } + + dayStrs := strings.Split(weekdaysStr, ",") + + for _, dayStr := range dayStrs { + day, ok := dayLookup[dayStr] + if !ok { + err = IncorrectFormatForSetting{Setting: config.Weekdays, Value: weekdaysStr} + return + } + weekdays = append(weekdays, day) + } + } + + var sessionTime *internal.TimeRange + sessionTime, err = internal.NewTimeRangeInLocation(start, end, weekdays, loc) + if err != nil { + return + } + s.SessionTime = sessionTime } else { + if settings.HasSetting(config.Weekdays) { + err = errors.New("Weekdays cannot be specified with StartDay/EndDay") + return + } + var startDayStr, endDayStr string if startDayStr, err = settings.Setting(config.StartDay); err != nil { return @@ -272,7 +302,12 @@ func (f sessionFactory) newSession( return } - s.SessionTime = internal.NewWeekRangeInLocation(start, end, startDay, endDay, loc) + var sessionTime *internal.TimeRange + sessionTime, err = internal.NewWeekRangeInLocation(start, end, startDay, endDay, loc) + if err != nil { + return + } + s.SessionTime = sessionTime } } diff --git a/session_factory_test.go b/session_factory_test.go index a86cfe369..ca9cc7a5a 100644 --- a/session_factory_test.go +++ b/session_factory_test.go @@ -176,8 +176,9 @@ func (s *SessionFactorySuite) TestStartAndEndTime() { s.Nil(err) s.NotNil(session.SessionTime) + expectedRange, _ := internal.NewUTCTimeRange(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), []time.Weekday{}) s.Equal( - *internal.NewUTCTimeRange(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0)), + *expectedRange, *session.SessionTime, ) } @@ -191,8 +192,41 @@ func (s *SessionFactorySuite) TestStartAndEndTimeAndTimeZone() { s.Nil(err) s.NotNil(session.SessionTime) + expectedRange, _ := internal.NewTimeRangeInLocation(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), []time.Weekday{}, time.Local) s.Equal( - *internal.NewTimeRangeInLocation(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), time.Local), + *expectedRange, + *session.SessionTime, + ) +} + +func (s *SessionFactorySuite) TestStartAndEndTimeAndWeekdays() { + s.SessionSettings.Set(config.StartTime, "12:00:00") + s.SessionSettings.Set(config.EndTime, "14:00:00") + s.SessionSettings.Set(config.Weekdays, "Monday,Tuesday,Wednesday") + session, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App) + s.Nil(err) + s.NotNil(session.SessionTime) + + expectedRange, _ := internal.NewUTCTimeRange(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), []time.Weekday{time.Monday, time.Tuesday, time.Wednesday}) + s.Equal( + *expectedRange, + *session.SessionTime, + ) +} + +func (s *SessionFactorySuite) TestStartAndEndTimeAndTimeZoneAndWeekdays() { + s.SessionSettings.Set(config.StartTime, "12:00:00") + s.SessionSettings.Set(config.EndTime, "14:00:00") + s.SessionSettings.Set(config.TimeZone, "Local") + s.SessionSettings.Set(config.Weekdays, "Mon,Tue") + + session, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App) + s.Nil(err) + s.NotNil(session.SessionTime) + + expectedRange, _ := internal.NewTimeRangeInLocation(internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), []time.Weekday{time.Monday, time.Tuesday}, time.Local) + s.Equal( + *expectedRange, *session.SessionTime, ) } @@ -217,11 +251,13 @@ func (s *SessionFactorySuite) TestStartAndEndTimeAndStartAndEndDay() { s.Nil(err) s.NotNil(session.SessionTime) + expectedRange, _ := internal.NewUTCWeekRange( + internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), + time.Sunday, time.Thursday, + ) + s.Equal( - *internal.NewUTCWeekRange( - internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), - time.Sunday, time.Thursday, - ), + *expectedRange, *session.SessionTime, ) } @@ -238,11 +274,13 @@ func (s *SessionFactorySuite) TestStartAndEndTimeAndStartAndEndDayAndTimeZone() s.Nil(err) s.NotNil(session.SessionTime) + expectedRange, _ := internal.NewWeekRangeInLocation( + internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), + time.Sunday, time.Thursday, time.Local, + ) + s.Equal( - *internal.NewWeekRangeInLocation( - internal.NewTimeOfDay(12, 0, 0), internal.NewTimeOfDay(14, 0, 0), - time.Sunday, time.Thursday, time.Local, - ), + *expectedRange, *session.SessionTime, ) } @@ -281,6 +319,46 @@ func (s *SessionFactorySuite) TestInvalidTimeZone() { s.NotNil(err) } +func (s *SessionFactorySuite) TestInvalidWeekdays() { + s.SessionSettings.Set(config.StartTime, "12:00:00") + s.SessionSettings.Set(config.EndTime, "14:00:00") + + testcases := []struct { + label string + input string + }{ + { + label: "invalid day value", + input: "Monday,Tuesday,not valid", + }, + { + label: "invalid separator", + input: "Monday;Tuesday", + }, + { + label: "whitespace", + input: "Monday, Tuesday", + }, + { + label: "trailing comma", + input: "Monday,", + }, + { + label: "empty value", + input: "Monday,,Tuesday", + }, + } + + for _, testcase := range testcases { + s.T().Run(testcase.label, func(t *testing.T) { + s.SessionSettings.Set(config.Weekdays, testcase.input) + + _, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App) + s.NotNil(err) + }) + } +} + func (s *SessionFactorySuite) TestMissingStartOrEndDay() { s.SessionSettings.Set(config.StartTime, "12:00:00") s.SessionSettings.Set(config.EndTime, "14:00:00") @@ -314,6 +392,17 @@ func (s *SessionFactorySuite) TestStartOrEndDayParseError() { s.NotNil(err) } +func (s *SessionFactorySuite) TestStartEndDayWithWeekdaysError() { + s.SessionSettings.Set(config.StartTime, "12:00:00") + s.SessionSettings.Set(config.EndTime, "14:00:00") + s.SessionSettings.Set(config.StartDay, "Monday") + s.SessionSettings.Set(config.EndDay, "Wednesday") + s.SessionSettings.Set(config.Weekdays, "Monday,Tuesday,Wednesday") + + _, err := s.newSession(s.SessionID, s.MessageStoreFactory, s.SessionSettings, s.LogFactory, s.App) + s.NotNil(err) +} + func (s *SessionFactorySuite) TestDefaultApplVerID() { s.SessionID = SessionID{BeginString: BeginStringFIXT11, TargetCompID: "TW", SenderCompID: "ISLD"} diff --git a/session_test.go b/session_test.go index 293b94805..97469d8ee 100644 --- a/session_test.go +++ b/session_test.go @@ -341,10 +341,14 @@ func (s *SessionSuite) TestCheckSessionTimeInRange() { s.IncrNextSenderMsgSeqNum() s.IncrNextTargetMsgSeqNum() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Clock()), internal.NewTimeOfDay(now.Add(time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime s.session.CheckSessionTime(s.session, now) if test.after != nil { @@ -388,10 +392,14 @@ func (s *SessionSuite) TestCheckSessionTimeNotInRange() { s.IncrNextTargetMsgSeqNum() now := time.Now().UTC() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Add(time.Hour).Clock()), internal.NewTimeOfDay(now.Add(time.Duration(2)*time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime if test.expectOnLogout { s.MockApp.On("OnLogout") @@ -442,10 +450,14 @@ func (s *SessionSuite) TestCheckSessionTimeInRangeButNotSameRangeAsStore() { s.IncrNextTargetMsgSeqNum() now := time.Now().UTC() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Add(time.Duration(-1)*time.Hour).Clock()), internal.NewTimeOfDay(now.Add(time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime if test.expectOnLogout { s.MockApp.On("OnLogout") @@ -491,10 +503,14 @@ func (s *SessionSuite) TestIncomingNotInSessionTime() { s.IncrNextTargetMsgSeqNum() now := time.Now().UTC() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Add(time.Hour).Clock()), internal.NewTimeOfDay(now.Add(time.Duration(2)*time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime if test.expectOnLogout { s.MockApp.On("OnLogout") } @@ -540,10 +556,14 @@ func (s *SessionSuite) TestSendAppMessagesNotInSessionTime() { s.MockApp.AssertExpectations(s.T()) now := time.Now().UTC() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Add(time.Hour).Clock()), internal.NewTimeOfDay(now.Add(time.Duration(2)*time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime if test.expectOnLogout { s.MockApp.On("OnLogout") } @@ -585,10 +605,14 @@ func (s *SessionSuite) TestTimeoutNotInSessionTime() { s.IncrNextTargetMsgSeqNum() now := time.Now().UTC() - s.session.SessionTime = internal.NewUTCTimeRange( + sessionTime, err := internal.NewUTCTimeRange( internal.NewTimeOfDay(now.Add(time.Hour).Clock()), internal.NewTimeOfDay(now.Add(time.Duration(2)*time.Hour).Clock()), + []time.Weekday{}, ) + s.Assert().Nil(err) + + s.session.SessionTime = sessionTime if test.expectOnLogout { s.MockApp.On("OnLogout") } From c46f6510799457f4fe9a213665ccfa4de56b07c6 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Sat, 24 Sep 2022 11:26:43 +0200 Subject: [PATCH 008/178] Remove unsused Message.keepMessage Signed-off-by: Sylvain Rabot --- in_session.go | 2 -- message.go | 3 --- 2 files changed, 5 deletions(-) diff --git a/in_session.go b/in_session.go index 3ca45d7bd..15fa6bc70 100644 --- a/in_session.go +++ b/in_session.go @@ -275,8 +275,6 @@ func (state inSession) processReject(session *session, msg *Message, rej Message } nextState.messageStash[TypedError.ReceivedTarget] = msg - //do not reclaim stashed message - msg.keepMessage = true return nextState diff --git a/message.go b/message.go index d76e5ca44..256ddc814 100644 --- a/message.go +++ b/message.go @@ -89,9 +89,6 @@ type Message struct { //field bytes as they appear in the raw message fields []TagValue - - //flag is true if this message should not be returned to pool after use - keepMessage bool } //ToMessage returns the message itself From a6c4bb93b23bd5d527349eb740a7f3c5d680d2d3 Mon Sep 17 00:00:00 2001 From: Sylvain Rabot Date: Sat, 24 Sep 2022 12:29:11 +0200 Subject: [PATCH 009/178] Improve output of cmd/generate-fix Signed-off-by: Sylvain Rabot --- cmd/generate-fix/internal/template_helpers.go | 31 +++++++--- cmd/generate-fix/internal/templates.go | 59 ++++++++++++++----- 2 files changed, 68 insertions(+), 22 deletions(-) diff --git a/cmd/generate-fix/internal/template_helpers.go b/cmd/generate-fix/internal/template_helpers.go index 55de54481..abc20c246 100644 --- a/cmd/generate-fix/internal/template_helpers.go +++ b/cmd/generate-fix/internal/template_helpers.go @@ -77,8 +77,8 @@ func checkFieldTimeRequired(f *datadictionary.FieldDef) (required bool, err erro return } -func collectExtraImports(m *datadictionary.MessageDef) (imports []string, err error) { - var timeRequired, decimalRequired bool +func collectStandardImports(m *datadictionary.MessageDef) (imports []string, err error) { + var timeRequired bool for _, f := range m.Fields { if !timeRequired { if timeRequired, err = checkFieldTimeRequired(f); err != nil { @@ -86,21 +86,32 @@ func collectExtraImports(m *datadictionary.MessageDef) (imports []string, err er } } + if timeRequired { + break + } + } + + if timeRequired { + imports = append(imports, "time") + } + + return +} + +func collectExtraImports(m *datadictionary.MessageDef) (imports []string, err error) { + var decimalRequired bool + for _, f := range m.Fields { if !decimalRequired { if decimalRequired, err = checkFieldDecimalRequired(f); err != nil { return } } - if decimalRequired && timeRequired { + if decimalRequired { break } } - if timeRequired { - imports = append(imports, "time") - } - if decimalRequired { imports = append(imports, "github.com/shopspring/decimal") } @@ -180,7 +191,7 @@ func quickfixType(field *datadictionary.FieldType) (quickfixType string, err err fallthrough case "MONTHYEAR": fallthrough - case "LOCALMKTDATE": + case "LOCALMKTTIME", "LOCALMKTDATE": fallthrough case "TIME": fallthrough @@ -204,6 +215,8 @@ func quickfixType(field *datadictionary.FieldType) (quickfixType string, err err fallthrough case "TZTIMESTAMP": fallthrough + case "XID", "XIDREF": + fallthrough case "STRING": quickfixType = "FIXString" @@ -218,6 +231,8 @@ func quickfixType(field *datadictionary.FieldType) (quickfixType string, err err fallthrough case "SEQNUM": fallthrough + case "TAGNUM": + fallthrough case "INT": quickfixType = "FIXInt" diff --git a/cmd/generate-fix/internal/templates.go b/cmd/generate-fix/internal/templates.go index cae2d567d..9ce81ccd3 100644 --- a/cmd/generate-fix/internal/templates.go +++ b/cmd/generate-fix/internal/templates.go @@ -24,6 +24,7 @@ func init() { "quickfixType": quickfixType, "quickfixValueType": quickfixValueType, "getGlobalFieldType": getGlobalFieldType, + "collectStandardImports": collectStandardImports, "collectExtraImports": collectExtraImports, "checkIfDecimalImportRequiredForFields": checkIfDecimalImportRequiredForFields, "checkIfEnumImportRequired": checkIfEnumImportRequired, @@ -111,7 +112,14 @@ func ({{ template "receiver" }} {{ $.Name }}) Has{{ .Name}}() bool { {{ define "group_template" }} quickfix.GroupTemplate{ -{{- range $index, $field := . }}{{if $index}},{{end}}{{if $field.IsGroup }}New{{ $field.Name }}RepeatingGroup(){{else}}quickfix.GroupElement(tag.{{$field.Name}}){{ end }}{{ end }} } +{{- range $index, $field := . }} + {{- if $field.IsGroup }} + New{{ $field.Name }}RepeatingGroup(), + {{- else}} + quickfix.GroupElement(tag.{{$field.Name}}), + {{- end }} +{{- end }} +} {{- end }} {{ define "field_args" }} @@ -139,7 +147,11 @@ type {{ .Name }}RepeatingGroup struct { // New{{ .Name }}RepeatingGroup returns an initialized, {{ .Name }}RepeatingGroup. func New{{ .Name }}RepeatingGroup() {{ .Name }}RepeatingGroup { return {{ .Name }}RepeatingGroup{ - quickfix.NewRepeatingGroup(tag.{{ .Name }}, {{ template "group_template" .Fields }})} + quickfix.NewRepeatingGroup( + tag.{{ .Name }}, + {{- template "group_template" .Fields }}, + ), + } } // Add create and append a new {{ .Name }} to this group. @@ -160,12 +172,17 @@ func ({{ template "receiver" }} {{ .Name}}RepeatingGroup) Get(i int) {{ .Name }} {{ define "receiver" }}h{{ end }} package {{ .Package }} -import( +import ( + {{- if collectStandardImports .MessageDef }} + {{- range collectStandardImports .MessageDef }} + "{{ . }}" + {{- end }}{{ "\n" }} + {{- end }} + {{- if collectExtraImports .MessageDef }} {{- range collectExtraImports .MessageDef }} "{{ . }}" + {{- end }}{{ "\n" }} {{- end }} - - "github.com/quickfixgo/quickfix" {{- if checkIfEnumImportRequired .MessageDef}} "{{ importRootPath }}/enum" @@ -196,11 +213,17 @@ func NewHeader(header *quickfix.Header) (h Header) { {{ define "receiver" }}t{{ end }} package {{ .Package }} -import( +import ( + {{- if collectStandardImports .MessageDef }} + {{- range collectStandardImports .MessageDef }} + "{{ . }}" + {{- end }}{{ "\n" }} + {{- end }} + {{- if collectExtraImports .MessageDef }} {{- range collectExtraImports .MessageDef }} "{{ . }}" + {{- end }}{{ "\n" }} {{- end }} - "github.com/quickfixgo/quickfix" {{- if checkIfEnumImportRequired .MessageDef}} "{{ importRootPath }}/enum" @@ -224,11 +247,17 @@ type Trailer struct { {{ define "receiver" }}m{{ end }} package {{ .Package }} -import( +import ( + {{- if collectStandardImports .MessageDef }} + {{- range collectStandardImports .MessageDef }} + "{{ . }}" + {{- end }}{{ "\n" }} + {{- end }} + {{- if collectExtraImports .MessageDef }} {{- range collectExtraImports .MessageDef }} "{{ . }}" + {{- end }}{{ "\n" }} {{- end }} - "github.com/quickfixgo/quickfix" {{- if checkIfEnumImportRequired .MessageDef}} "{{ importRootPath }}/enum" @@ -296,23 +325,25 @@ func Route(router RouteOut) (string, string, quickfix.MessageRoute) { TagTemplate = template.Must(template.New("Tag").Parse(` package tag -import("github.com/quickfixgo/quickfix") +import "github.com/quickfixgo/quickfix" const ( {{- range .}} -{{ .Name }} quickfix.Tag = {{ .Tag }} +{{ .Name }} quickfix.Tag = {{ .Tag }} {{- end }} ) `)) FieldTemplate = template.Must(template.New("Field").Funcs(tmplFuncs).Parse(` package field -import( +import ( + "time" + + {{ if checkIfDecimalImportRequiredForFields . }}"github.com/shopspring/decimal"{{ end }} + "github.com/quickfixgo/quickfix" "{{ importRootPath }}/enum" "{{ importRootPath }}/tag" -{{ if checkIfDecimalImportRequiredForFields . }} "github.com/shopspring/decimal" {{ end }} - "time" ) {{ range . }} From 8ed145d7243bdcdec4f367eecc55f5c7a405a25a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 5 Jan 2023 00:07:55 +0000 Subject: [PATCH 010/178] Bump golang.org/x/net from 0.4.0 to 0.5.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.5.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/compare/v0.4.0...v0.5.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 952abfa45..10cbdb8b1 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.1 go.mongodb.org/mongo-driver v1.11.1 - golang.org/x/net v0.4.0 + golang.org/x/net v0.5.0 ) require ( @@ -27,7 +27,7 @@ require ( github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect golang.org/x/crypto v0.3.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/text v0.5.0 // indirect + golang.org/x/text v0.6.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index a1a76b93c..376aa7687 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= -golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -73,8 +73,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= -golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 9c874d8fb94a79d8365f7d570ce7427be0ed6928 Mon Sep 17 00:00:00 2001 From: Hyde Zhang Date: Fri, 24 Sep 2021 16:18:08 +0100 Subject: [PATCH 011/178] Fix repeating group read tags lost --- repeating_group.go | 1 + repeating_group_test.go | 2 ++ 2 files changed, 3 insertions(+) diff --git a/repeating_group.go b/repeating_group.go index 173cfa116..1cbbc8e2a 100644 --- a/repeating_group.go +++ b/repeating_group.go @@ -202,6 +202,7 @@ func (f *RepeatingGroup) Read(tv []TagValue) ([]TagValue, error) { group.rwLock.Lock() group.tagLookup[tvRange[0].tag] = tvRange + group.tags = append(group.tags, gi.Tag()) group.rwLock.Unlock() } diff --git a/repeating_group_test.go b/repeating_group_test.go index 448e39d6a..955e3b7da 100644 --- a/repeating_group_test.go +++ b/repeating_group_test.go @@ -185,6 +185,8 @@ func TestRepeatingGroup_Read(t *testing.T) { for _, expected := range test.expectedGroupTvs[g] { var actual FIXString require.Nil(t, group.GetField(expected.tag, &actual)) + require.NotNil(t, group.tags) + require.Equal(t, len(group.tags), len(group.tagLookup)) if !bytes.Equal(expected.value, []byte(actual)) { t.Errorf("%v, %v: expected %s, got %s", g, expected.tag, expected.value, actual) From 97461150fbecc974d0d435b9f3dff4d50c515fe6 Mon Sep 17 00:00:00 2001 From: Russell Scheerer Date: Thu, 1 Dec 2022 11:26:13 -0500 Subject: [PATCH 012/178] Add sessionId to global logs where possible --- acceptor.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acceptor.go b/acceptor.go index 3d72ba20e..656463cbe 100644 --- a/acceptor.go +++ b/acceptor.go @@ -298,7 +298,7 @@ func (a *Acceptor) handleConnection(netConn net.Conn) { // We have a session ID and a network connection. This seems to be a good place for any custom authentication logic. if a.connectionValidator != nil { if err := a.connectionValidator.Validate(netConn, sessID); err != nil { - a.globalLog.OnEventf("Unable to validate a connection %v", err.Error()) + a.globalLog.OnEventf("Unable to validate a connection for session %v: %v", sessID, err.Error()) return } } @@ -328,7 +328,7 @@ func (a *Acceptor) handleConnection(netConn net.Conn) { msgOut := make(chan []byte) if err := session.connect(msgIn, msgOut); err != nil { - a.globalLog.OnEventf("Unable to accept %v", err.Error()) + a.globalLog.OnEventf("Unable to accept session %v connection: %v", sessID, err.Error()) return } From f26aaade3055bb53265f00f44dfb375ae986f507 Mon Sep 17 00:00:00 2001 From: Lord Date: Thu, 21 May 2020 23:11:09 -0500 Subject: [PATCH 013/178] ignore data in xmldata field --- message.go | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/message.go b/message.go index 0a637346b..6945e2301 100644 --- a/message.go +++ b/message.go @@ -190,6 +190,8 @@ func ParseMessageWithDataDictionary( return } + prevTag := tagMsgType + msg.Header.add(msg.fields[fieldIndex : fieldIndex+1]) fieldIndex++ @@ -197,7 +199,11 @@ func ParseMessageWithDataDictionary( foundBody := false for { parsedFieldBytes = &msg.fields[fieldIndex] - rawBytes, err = extractField(parsedFieldBytes, rawBytes) + if prevTag == tagXMLDataLen { + rawBytes, err = extractXMLDataField(parsedFieldBytes, rawBytes) + } else { + rawBytes, err = extractField(parsedFieldBytes, rawBytes) + } if err != nil { return } @@ -220,6 +226,7 @@ func ParseMessageWithDataDictionary( msg.bodyBytes = rawBytes } + prevTag = parsedFieldBytes.tag fieldIndex++ } @@ -338,6 +345,30 @@ func extractSpecificField(field *TagValue, expectedTag Tag, buffer []byte) (remB return } +func extractXMLDataField(parsedFieldBytes *TagValue, buffer []byte) (remBytes []byte, err error) { + endIndex := bytes.IndexByte(buffer, '>') + if endIndex == -1 { + err = parseError{OrigError: "extractField: No Trailing Delim in " + string(buffer)} + remBytes = buffer + return + } + + endIndex = bytes.IndexByte(buffer[endIndex+1:], '>') + if endIndex == -1 { + err = parseError{OrigError: "extractField: No Trailing Delim in " + string(buffer)} + remBytes = buffer + return + } + + tempEndIndex := bytes.IndexByte(buffer[endIndex:], '\001') + endIndex += tempEndIndex + tempEndIndex = bytes.IndexByte(buffer[endIndex+1:], '\001') + endIndex += tempEndIndex + 1 + + err = parsedFieldBytes.parse(buffer[:endIndex+1]) + return buffer[(endIndex + 1):], err +} + func extractField(parsedFieldBytes *TagValue, buffer []byte) (remBytes []byte, err error) { endIndex := bytes.IndexByte(buffer, '\001') if endIndex == -1 { From 1ce30ebdce646424876ef299984bc090c5b4a719 Mon Sep 17 00:00:00 2001 From: Lord Date: Wed, 27 May 2020 15:37:07 -0500 Subject: [PATCH 014/178] Properly process CME XMLData for 35=n --- message.go | 34 +++++++++++++++------------------- message_test.go | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/message.go b/message.go index 6945e2301..5f185ed2f 100644 --- a/message.go +++ b/message.go @@ -190,7 +190,9 @@ func ParseMessageWithDataDictionary( return } - prevTag := tagMsgType + //prevTag := tagMsgType + xmlDataLen := 0 + xmlDataMsg := false msg.Header.add(msg.fields[fieldIndex : fieldIndex+1]) fieldIndex++ @@ -199,8 +201,10 @@ func ParseMessageWithDataDictionary( foundBody := false for { parsedFieldBytes = &msg.fields[fieldIndex] - if prevTag == tagXMLDataLen { - rawBytes, err = extractXMLDataField(parsedFieldBytes, rawBytes) + if xmlDataLen > 0 { + rawBytes, err = extractXMLDataField(parsedFieldBytes, rawBytes, xmlDataLen) + xmlDataLen = 0 + xmlDataMsg = true } else { rawBytes, err = extractField(parsedFieldBytes, rawBytes) } @@ -226,7 +230,10 @@ func ParseMessageWithDataDictionary( msg.bodyBytes = rawBytes } - prevTag = parsedFieldBytes.tag + //prevTag = parsedFieldBytes.tag + if parsedFieldBytes.tag == tagXMLDataLen { + xmlDataLen, _ = msg.Header.GetInt(tagXMLDataLen) + } fieldIndex++ } @@ -247,7 +254,7 @@ func ParseMessageWithDataDictionary( bodyLength, err := msg.Header.GetInt(tagBodyLength) if err != nil { err = parseError{OrigError: err.Error()} - } else if length != bodyLength { + } else if length != bodyLength && !xmlDataMsg { err = parseError{OrigError: fmt.Sprintf("Incorrect Message Length, expected %d, got %d", bodyLength, length)} } @@ -345,25 +352,14 @@ func extractSpecificField(field *TagValue, expectedTag Tag, buffer []byte) (remB return } -func extractXMLDataField(parsedFieldBytes *TagValue, buffer []byte) (remBytes []byte, err error) { - endIndex := bytes.IndexByte(buffer, '>') - if endIndex == -1 { - err = parseError{OrigError: "extractField: No Trailing Delim in " + string(buffer)} - remBytes = buffer - return - } - - endIndex = bytes.IndexByte(buffer[endIndex+1:], '>') +func extractXMLDataField(parsedFieldBytes *TagValue, buffer []byte, dataLen int) (remBytes []byte, err error) { + endIndex := bytes.IndexByte(buffer, '=') if endIndex == -1 { err = parseError{OrigError: "extractField: No Trailing Delim in " + string(buffer)} remBytes = buffer return } - - tempEndIndex := bytes.IndexByte(buffer[endIndex:], '\001') - endIndex += tempEndIndex - tempEndIndex = bytes.IndexByte(buffer[endIndex+1:], '\001') - endIndex += tempEndIndex + 1 + endIndex += dataLen + 1 err = parsedFieldBytes.parse(buffer[:endIndex+1]) return buffer[(endIndex + 1):], err diff --git a/message_test.go b/message_test.go index 40b063ca1..1a46a62d8 100644 --- a/message_test.go +++ b/message_test.go @@ -13,9 +13,9 @@ import ( func BenchmarkParseMessage(b *testing.B) { rawMsg := bytes.NewBufferString("8=FIX.4.29=10435=D34=249=TW52=20140515-19:49:56.65956=ISLD11=10021=140=154=155=TSLA60=00010101-00:00:00.00010=039") - var msg Message + msg := NewMessage() for i := 0; i < b.N; i++ { - _ = ParseMessage(&msg, rawMsg) + _ = ParseMessage(msg, rawMsg) } } @@ -32,6 +32,16 @@ func (s *MessageSuite) SetupTest() { s.msg = NewMessage() } +func TestXMLNonFIX(t *testing.T) { + rawMsg := bytes.NewBufferString("8=FIX.4.29=37235=n34=25512369=148152=20200522-07:05:33.75649=CME50=G56=OAEAAAN57=TRADE_CAPTURE143=US,IL212=261213=8=FIX.4.29=22535=BZ34=6549369=651852=20200522-07:05:33.74649=CME50=G56=9Q5000N57=DUMMY143=US,IL11=ACP159013113373460=20200522-07:05:33.734533=0893=Y1028=Y1300=991369=99612:325081373=31374=91375=15979=159013113373461769710=16710=245\"") + msg := NewMessage() + _ = ParseMessage(msg, rawMsg) + + if !msg.Header.Has(tagXMLData) { + t.Error("Expected xmldata tag") + } +} + func (s *MessageSuite) TestParseMessageEmpty() { rawMsg := bytes.NewBufferString("") From 8a2144a438445349de04c07d02fbb8bcb40df063 Mon Sep 17 00:00:00 2001 From: Michael Ackley Date: Sun, 29 Jan 2023 19:18:12 -0600 Subject: [PATCH 015/178] Adds license info to src file headers and formats comments. --- .golangci.yml | 1 + LICENSE.txt => LICENSE | 2 +- accepter_test.go | 15 +++++ acceptor.go | 15 +++++ application.go | 29 +++++++--- begin_string.go | 17 +++++- cmd/generate-fix/generate-fix.go | 2 +- cmd/generate-fix/internal/globals.go | 6 +- cmd/generate-fix/internal/template_helpers.go | 2 +- config/configuration.go | 4 +- connection.go | 15 +++++ connection_internal_test.go | 15 +++++ datadictionary/datadictionary.go | 51 ++++++++--------- datadictionary/xml.go | 2 +- dialer.go | 15 +++++ dialer_test.go | 15 +++++ doc.go | 21 +++++-- errors.go | 41 ++++++++----- errors_test.go | 15 +++++ field.go | 37 ++++++++---- field_map.go | 57 ++++++++++++------- field_map_test.go | 15 +++++ file_log.go | 15 +++++ file_log_test.go | 15 +++++ filestore.go | 39 +++++++++---- filestore_test.go | 17 +++++- fileutil.go | 21 ++++++- fileutil_test.go | 15 +++++ fix_boolean.go | 17 +++++- fix_boolean_test.go | 15 +++++ fix_bytes.go | 17 +++++- fix_bytes_test.go | 15 +++++ fix_decimal.go | 19 ++++++- fix_decimal_test.go | 15 +++++ fix_float.go | 21 ++++++- fix_float_test.go | 15 +++++ fix_int.go | 23 ++++++-- fix_int_test.go | 15 +++++ fix_string.go | 17 +++++- fix_string_test.go | 15 +++++ fix_utc_timestamp.go | 25 ++++++-- fix_utc_timestamp_test.go | 15 +++++ in_session.go | 21 ++++++- in_session_test.go | 17 +++++- initiator.go | 23 ++++++-- internal/event.go | 10 ++-- internal/session_settings.go | 6 +- internal/time_range.go | 20 +++---- latent_state.go | 15 +++++ latent_state_test.go | 15 +++++ log.go | 29 +++++++--- logon_state.go | 15 +++++ logon_state_test.go | 21 ++++++- logout_state.go | 15 +++++ logout_state_test.go | 15 +++++ message.go | 57 ++++++++++++------- message_router.go | 23 ++++++-- message_router_test.go | 15 +++++ message_test.go | 19 ++++++- mongostore.go | 51 +++++++++++------ mongostore_test.go | 17 +++++- msg_type.go | 15 +++++ not_session_time.go | 15 +++++ not_session_time_test.go | 15 +++++ null_log.go | 15 +++++ parser.go | 23 ++++++-- parser_test.go | 15 +++++ pending_timeout.go | 15 +++++ pending_timeout_test.go | 15 +++++ quickfix_test.go | 17 +++++- registry.go | 23 ++++++-- repeating_group.go | 55 +++++++++++------- repeating_group_test.go | 15 +++++ resend_state.go | 19 ++++++- resend_state_test.go | 21 ++++++- screen_log.go | 15 +++++ session.go | 37 ++++++++---- session_factory.go | 21 ++++++- session_factory_test.go | 15 +++++ session_id.go | 19 ++++++- session_id_test.go | 15 +++++ session_rejects.go | 15 +++++ session_settings.go | 27 +++++++-- session_settings_test.go | 15 +++++ session_state.go | 33 ++++++++--- session_test.go | 41 ++++++++----- settings.go | 23 ++++++-- settings_test.go | 15 +++++ sqlstore.go | 39 +++++++++---- sqlstore_test.go | 17 +++++- store.go | 25 ++++++-- store_test.go | 19 ++++++- tag.go | 21 ++++++- tag_value.go | 17 +++++- tag_value_test.go | 15 +++++ tls.go | 15 +++++ tls_test.go | 15 +++++ validation.go | 25 ++++++-- validation_test.go | 50 +++++++++------- 99 files changed, 1652 insertions(+), 337 deletions(-) rename LICENSE.txt => LICENSE (95%) diff --git a/.golangci.yml b/.golangci.yml index 7d3a47ddb..cf2a5fff9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,6 +17,7 @@ linters: - revive - unused - staticcheck + - godot linters-settings: gofmt: diff --git a/LICENSE.txt b/LICENSE similarity index 95% rename from LICENSE.txt rename to LICENSE index d9eb36409..273a59dad 100644 --- a/LICENSE.txt +++ b/LICENSE @@ -1,6 +1,6 @@ The QuickFIX Software License, Version 1.0 -Copyright (c) 2001-2010 quickfixengine.org All rights +Copyright (c) 2001- quickfixengine.org All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/accepter_test.go b/accepter_test.go index 5e032cbb1..0d9f6487b 100644 --- a/accepter_test.go +++ b/accepter_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/acceptor.go b/acceptor.go index 656463cbe..879cdb17f 100644 --- a/acceptor.go +++ b/acceptor.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/application.go b/application.go index e7d76c60e..1d12419d3 100644 --- a/application.go +++ b/application.go @@ -1,26 +1,41 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix // Application interface should be implemented by FIX Applications. // This is the primary interface for processing messages from a FIX Session. type Application interface { - //OnCreate notification of a session begin created. + // OnCreate notification of a session begin created. OnCreate(sessionID SessionID) - //OnLogon notification of a session successfully logging on. + // OnLogon notification of a session successfully logging on. OnLogon(sessionID SessionID) - //OnLogout notification of a session logging off or disconnecting. + // OnLogout notification of a session logging off or disconnecting. OnLogout(sessionID SessionID) - //ToAdmin notification of admin message being sent to target. + // ToAdmin notification of admin message being sent to target. ToAdmin(message *Message, sessionID SessionID) - //ToApp notification of app message being sent to target. + // ToApp notification of app message being sent to target. ToApp(message *Message, sessionID SessionID) error - //FromAdmin notification of admin message being received from target. + // FromAdmin notification of admin message being received from target. FromAdmin(message *Message, sessionID SessionID) MessageRejectError - //FromApp notification of app message being received from target. + // FromApp notification of app message being received from target. FromApp(message *Message, sessionID SessionID) MessageRejectError } diff --git a/begin_string.go b/begin_string.go index b5d9f6f14..641ea7c6f 100644 --- a/begin_string.go +++ b/begin_string.go @@ -1,6 +1,21 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix -// FIX BeginString string values +// FIX BeginString string values. const ( BeginStringFIX40 = "FIX.4.0" BeginStringFIX41 = "FIX.4.1" diff --git a/cmd/generate-fix/generate-fix.go b/cmd/generate-fix/generate-fix.go index ae1749722..a24d39771 100644 --- a/cmd/generate-fix/generate-fix.go +++ b/cmd/generate-fix/generate-fix.go @@ -164,7 +164,7 @@ func main() { } switch pkg { - //uses fixt11 header/trailer + // Uses fixt11 header/trailer. case "fix50", "fix50sp1", "fix50sp2": default: waitGroup.Add(1) diff --git a/cmd/generate-fix/internal/globals.go b/cmd/generate-fix/internal/globals.go index 45e49467d..bf935b4db 100644 --- a/cmd/generate-fix/internal/globals.go +++ b/cmd/generate-fix/internal/globals.go @@ -14,7 +14,7 @@ var ( GlobalFieldTypes []*datadictionary.FieldType ) -//sort fieldtypes by name +// Sort fieldtypes by name. type byFieldName []*datadictionary.FieldType func (n byFieldName) Len() int { return len(n) } @@ -36,14 +36,14 @@ func BuildGlobalFieldTypes(specs []*datadictionary.DataDictionary) { for _, spec := range specs { for _, field := range spec.FieldTypeByTag { if oldField, ok := globalFieldTypesLookup[field.Name()]; ok { - //merge old enums with new + // Merge old enums with new. if len(oldField.Enums) > 0 && field.Enums == nil { field.Enums = make(map[string]datadictionary.Enum) } for enumVal, enum := range oldField.Enums { if _, ok := field.Enums[enumVal]; !ok { - //Verify an existing enum doesn't have the same description. Keep newer enum + // Verify an existing enum doesn't have the same description. Keep newer enum. okToKeepEnum := true for _, newEnum := range field.Enums { if newEnum.Description == enum.Description { diff --git a/cmd/generate-fix/internal/template_helpers.go b/cmd/generate-fix/internal/template_helpers.go index e4dcce727..932f4792b 100644 --- a/cmd/generate-fix/internal/template_helpers.go +++ b/cmd/generate-fix/internal/template_helpers.go @@ -306,7 +306,7 @@ func routerBeginString(spec *datadictionary.DataDictionary) (routerBeginString s routerBeginString = "FIXT.1.1" case spec.Major != 5 && spec.ServicePack == 0: routerBeginString = fmt.Sprintf("FIX.%v.%v", spec.Major, spec.Minor) - //ApplVerID enums + // ApplVerID enums. case spec.Major == 2: routerBeginString = "0" case spec.Major == 3: diff --git a/config/configuration.go b/config/configuration.go index 2af864fd9..431be8ea7 100644 --- a/config/configuration.go +++ b/config/configuration.go @@ -1,8 +1,8 @@ package config -//NOTE: Additions to this file should be made to both config/doc.go and http://www.quickfixgo.org/docs/ +// NOTE: Additions to this file should be made to both config/doc.go and http://www.quickfixgo.org/docs/ -// Const configuration settings +// Const configuration settings. const ( BeginString string = "BeginString" SenderCompID string = "SenderCompID" diff --git a/connection.go b/connection.go index 4e5768a36..c006560f4 100644 --- a/connection.go +++ b/connection.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "io" diff --git a/connection_internal_test.go b/connection_internal_test.go index 54a9f347f..1ee4d13e8 100644 --- a/connection_internal_test.go +++ b/connection_internal_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/datadictionary/datadictionary.go b/datadictionary/datadictionary.go index b1dc8ef3f..9342b3dd5 100644 --- a/datadictionary/datadictionary.go +++ b/datadictionary/datadictionary.go @@ -23,13 +23,13 @@ type DataDictionary struct { Trailer *MessageDef } -// MessagePart can represent a Field, Repeating Group, or Component +// MessagePart can represent a Field, Repeating Group, or Component. type MessagePart interface { Name() string Required() bool } -// messagePartWithFields is a MessagePart with multiple Fields +// messagePartWithFields is a MessagePart with multiple Fields. type messagePartWithFields interface { MessagePart Fields() []*FieldDef @@ -45,7 +45,7 @@ type ComponentType struct { requiredParts []MessagePart } -// NewComponentType returns an initialized component type +// NewComponentType returns an initialized component type. func NewComponentType(name string, parts []MessagePart) *ComponentType { comp := ComponentType{ name: name, @@ -77,20 +77,20 @@ func NewComponentType(name string, parts []MessagePart) *ComponentType { return &comp } -// Name returns the name of this component type +// Name returns the name of this component type. func (c ComponentType) Name() string { return c.name } // Fields returns all fields contained in this component. Includes fields -// encapsulated in components of this component +// encapsulated in components of this component. func (c ComponentType) Fields() []*FieldDef { return c.fields } -// RequiredFields returns those fields that are required for this component +// RequiredFields returns those fields that are required for this component. func (c ComponentType) RequiredFields() []*FieldDef { return c.requiredFields } -// RequiredParts returns those parts that are required for this component +// RequiredParts returns those parts that are required for this component. func (c ComponentType) RequiredParts() []MessagePart { return c.requiredParts } -// Parts returns all parts in declaration order contained in this component +// Parts returns all parts in declaration order contained in this component. func (c ComponentType) Parts() []MessagePart { return c.parts } // TagSet is set for tags. @@ -101,13 +101,13 @@ func (t TagSet) Add(tag int) { t[tag] = struct{}{} } -// Component is a Component as it appears in a given MessageDef +// Component is a Component as it appears in a given MessageDef. type Component struct { *ComponentType required bool } -// NewComponent returns an initialized Component instance +// NewComponent returns an initialized Component instance. func NewComponent(ct *ComponentType, required bool) *Component { return &Component{ ComponentType: ct, @@ -116,10 +116,10 @@ func NewComponent(ct *ComponentType, required bool) *Component { } // Required returns true if this component is required for the containing -// MessageDef +// MessageDef. func (c Component) Required() bool { return c.required } -// Field models a field or repeating group in a message +// Field models a field or repeating group in a message. type Field interface { Tag() int } @@ -135,7 +135,7 @@ type FieldDef struct { requiredFields []*FieldDef } -// NewFieldDef returns an initialized FieldDef +// NewFieldDef returns an initialized FieldDef. func NewFieldDef(fieldType *FieldType, required bool) *FieldDef { return &FieldDef{ FieldType: fieldType, @@ -143,7 +143,7 @@ func NewFieldDef(fieldType *FieldType, required bool) *FieldDef { } } -// NewGroupFieldDef returns an initialized FieldDef for a repeating group +// NewGroupFieldDef returns an initialized FieldDef for a repeating group. func NewGroupFieldDef(fieldType *FieldType, required bool, parts []MessagePart) *FieldDef { field := FieldDef{ FieldType: fieldType, @@ -179,7 +179,7 @@ func NewGroupFieldDef(fieldType *FieldType, required bool, parts []MessagePart) } // Required returns true if this FieldDef is required for the containing -// MessageDef +// MessageDef. func (f FieldDef) Required() bool { return f.required } // IsGroup is true if the field is a repeating group. @@ -188,11 +188,11 @@ func (f FieldDef) IsGroup() bool { } // RequiredParts returns those parts that are required for this FieldDef. IsGroup -// must return true +// must return true. func (f FieldDef) RequiredParts() []MessagePart { return f.requiredParts } // RequiredFields returns those fields that are required for this FieldDef. IsGroup -// must return true +// must return true. func (f FieldDef) RequiredFields() []*FieldDef { return f.requiredFields } func (f FieldDef) childTags() []int { @@ -214,7 +214,7 @@ type FieldType struct { Enums map[string]Enum } -// NewFieldType returns a pointer to an initialized FieldType +// NewFieldType returns a pointer to an initialized FieldType. func NewFieldType(name string, tag int, fixType string) *FieldType { return &FieldType{ name: name, @@ -223,10 +223,10 @@ func NewFieldType(name string, tag int, fixType string) *FieldType { } } -// Name returns the name for this FieldType +// Name returns the name for this FieldType. func (f FieldType) Name() string { return f.name } -// Tag returns the tag for this fieldType +// Tag returns the tag for this fieldType. func (f FieldType) Tag() int { return f.tag } // Enum is a container for value and description. @@ -240,8 +240,7 @@ type MessageDef struct { Name string MsgType string Fields map[int]*FieldDef - //Parts are the MessageParts of contained in this MessageDef in declaration - //order + // Parts are the MessageParts of contained in this MessageDef in declaration order. Parts []MessagePart requiredParts []MessagePart @@ -249,10 +248,10 @@ type MessageDef struct { Tags TagSet } -// RequiredParts returns those parts that are required for this Message +// RequiredParts returns those parts that are required for this Message. func (m MessageDef) RequiredParts() []MessagePart { return m.requiredParts } -// NewMessageDef returns a pointer to an initialized MessageDef +// NewMessageDef returns a pointer to an initialized MessageDef. func NewMessageDef(name, msgType string, parts []MessagePart) *MessageDef { msg := MessageDef{ Name: name, @@ -283,8 +282,8 @@ func NewMessageDef(name, msgType string, parts []MessagePart) *MessageDef { switch pType := part.(type) { case messagePartWithFields: for _, f := range pType.Fields() { - //field if required in component is required in message only if - //component is required + // Field if required in component is required in message only if + // component is required. processField(f, pType.Required()) } diff --git a/datadictionary/xml.go b/datadictionary/xml.go index 759a082f4..a25e5b4e0 100644 --- a/datadictionary/xml.go +++ b/datadictionary/xml.go @@ -41,7 +41,7 @@ type XMLValue struct { Description string `xml:"description,attr"` } -// XMLComponentMember represents child elements of header, trailer, messages/message, and components/component elements +// XMLComponentMember represents child elements of header, trailer, messages/message, and components/component elements. type XMLComponentMember struct { XMLName xml.Name Name string `xml:"name,attr"` diff --git a/dialer.go b/dialer.go index 1eb28ad04..d1654aa31 100644 --- a/dialer.go +++ b/dialer.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/dialer_test.go b/dialer_test.go index 47bf79d08..5f8599c1e 100644 --- a/dialer_test.go +++ b/dialer_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/doc.go b/doc.go index 76f7b7b71..3d53535c3 100644 --- a/doc.go +++ b/doc.go @@ -1,6 +1,19 @@ -/* -Package quickfix is a full featured messaging engine for the FIX protocol. It is a 100% Go open source implementation of the popular C++ QuickFIX engine (http://quickfixengine.org). +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. -User manual and additional information available at http://quickfixgo.org -*/ +// Package quickfix is a full featured messaging engine for the FIX protocol. It is a 100% Go open source implementation of the popular C++ QuickFIX engine (http://quickfixengine.org). +// +// User manual and additional information available at https://quickfixgo.org package quickfix diff --git a/errors.go b/errors.go index f69e9c287..e9d120991 100644 --- a/errors.go +++ b/errors.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -5,7 +20,7 @@ import ( "fmt" ) -// ErrDoNotSend is a convenience error to indicate a DoNotSend in ToApp +// ErrDoNotSend is a convenience error to indicate a DoNotSend in ToApp. var ErrDoNotSend = errors.New("Do Not Send") // rejectReason enum values. @@ -31,30 +46,30 @@ const ( type MessageRejectError interface { error - //RejectReason, tag 373 for session rejects, tag 380 for business rejects. + // RejectReason, tag 373 for session rejects, tag 380 for business rejects. RejectReason() int BusinessRejectRefID() string RefTagID() *Tag IsBusinessReject() bool } -// RejectLogon indicates the application is rejecting permission to logon. Implements MessageRejectError +// RejectLogon indicates the application is rejecting permission to logon. Implements MessageRejectError. type RejectLogon struct { Text string } func (e RejectLogon) Error() string { return e.Text } -// RefTagID implements MessageRejectError +// RefTagID implements MessageRejectError. func (RejectLogon) RefTagID() *Tag { return nil } -// RejectReason implements MessageRejectError +// RejectReason implements MessageRejectError. func (RejectLogon) RejectReason() int { return 0 } -// BusinessRejectRefID implements MessageRejectError +// BusinessRejectRefID implements MessageRejectError. func (RejectLogon) BusinessRejectRefID() string { return "" } -// IsBusinessReject implements MessageRejectError +// IsBusinessReject implements MessageRejectError. func (RejectLogon) IsBusinessReject() bool { return false } type messageRejectError struct { @@ -71,19 +86,19 @@ func (e messageRejectError) RejectReason() int { return e.rejectReason func (e messageRejectError) BusinessRejectRefID() string { return e.businessRejectRefID } func (e messageRejectError) IsBusinessReject() bool { return e.isBusinessReject } -// NewMessageRejectError returns a MessageRejectError with the given error message, reject reason, and optional reftagid +// NewMessageRejectError returns a MessageRejectError with the given error message, reject reason, and optional reftagid. func NewMessageRejectError(err string, rejectReason int, refTagID *Tag) MessageRejectError { return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID} } // NewBusinessMessageRejectError returns a MessageRejectError with the given error mesage, reject reason, and optional reftagid. -// Reject is treated as a business level reject +// Reject is treated as a business level reject. func NewBusinessMessageRejectError(err string, rejectReason int, refTagID *Tag) MessageRejectError { return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID, isBusinessReject: true} } // NewBusinessMessageRejectErrorWithRefID returns a MessageRejectError with the given error mesage, reject reason, refID, and optional reftagid. -// Reject is treated as a business level reject +// Reject is treated as a business level reject. func NewBusinessMessageRejectErrorWithRefID(err string, rejectReason int, businessRejectRefID string, refTagID *Tag) MessageRejectError { return messageRejectError{text: err, rejectReason: rejectReason, refTagID: refTagID, businessRejectRefID: businessRejectRefID, isBusinessReject: true} } @@ -93,7 +108,7 @@ func IncorrectDataFormatForValue(tag Tag) MessageRejectError { return NewMessageRejectError("Incorrect data format for value", rejectReasonIncorrectDataFormatForValue, &tag) } -// repeatingGroupFieldsOutOfOrder returns an error indicating a problem parsing repeating groups fields +// repeatingGroupFieldsOutOfOrder returns an error indicating a problem parsing repeating groups fields. func repeatingGroupFieldsOutOfOrder(tag Tag, reason string) MessageRejectError { if reason != "" { reason = fmt.Sprintf("Repeating group fields out of order (%s)", reason) @@ -114,12 +129,12 @@ func ConditionallyRequiredFieldMissing(tag Tag) MessageRejectError { } // valueIsIncorrectNoTag returns an error indicating a field with value that is not valid. -// FIXME: to be compliant with legacy tests, for certain value issues, do not include reftag? (11c_NewSeqNoLess) +// FIXME: to be compliant with legacy tests, for certain value issues, do not include reftag? (11c_NewSeqNoLess). func valueIsIncorrectNoTag() MessageRejectError { return NewMessageRejectError("Value is incorrect (out of range) for this tag", rejectReasonValueIsIncorrect, nil) } -// InvalidMessageType returns an error to indicate an invalid message type +// InvalidMessageType returns an error to indicate an invalid message type. func InvalidMessageType() MessageRejectError { return NewMessageRejectError("Invalid MsgType", rejectReasonInvalidMsgType, nil) } diff --git a/errors_test.go b/errors_test.go index e612d3242..c5b77d9b6 100644 --- a/errors_test.go +++ b/errors_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/field.go b/field.go index 81a277cad..9dc00dac7 100644 --- a/field.go +++ b/field.go @@ -1,49 +1,64 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix -// FieldValueWriter is an interface for writing field values +// FieldValueWriter is an interface for writing field values. type FieldValueWriter interface { - //Write writes out the contents of the FieldValue to a []byte + // Write writes out the contents of the FieldValue to a `[]byte`. Write() []byte } -// FieldValueReader is an interface for reading field values +// FieldValueReader is an interface for reading field values. type FieldValueReader interface { - //Read reads the contents of the []byte into FieldValue. - //Returns an error if there are issues in the data processing + // Read reads the contents of the `[]byte` into FieldValue. + // Returns an error if there are issues in the data processing. Read([]byte) error } -// The FieldValue interface is used to write/extract typed field values to/from raw bytes +// The FieldValue interface is used to write/extract typed field values to/from raw bytes. type FieldValue interface { FieldValueWriter FieldValueReader } -// FieldWriter is an interface for a writing a field +// FieldWriter is an interface for a writing a field. type FieldWriter interface { Tag() Tag FieldValueWriter } -// Field is the interface implemented by all typed Fields in a Message +// Field is the interface implemented by all typed Fields in a Message. type Field interface { FieldWriter FieldValueReader } -// FieldGroupWriter is an interface for writing a FieldGroup +// FieldGroupWriter is an interface for writing a FieldGroup. type FieldGroupWriter interface { Tag() Tag Write() []TagValue } -// FieldGroupReader is an interface for reading a FieldGroup +// FieldGroupReader is an interface for reading a FieldGroup. type FieldGroupReader interface { Tag() Tag Read([]TagValue) ([]TagValue, error) } -// FieldGroup is the interface implemented by all typed Groups in a Message +// FieldGroup is the interface implemented by all typed Groups in a Message. type FieldGroup interface { Tag() Tag Write() []TagValue diff --git a/field_map.go b/field_map.go index 5d5f94269..e940790f5 100644 --- a/field_map.go +++ b/field_map.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -7,7 +22,7 @@ import ( "time" ) -// field stores a slice of TagValues +// field stores a slice of TagValues. type field []TagValue func fieldTag(f field) Tag { @@ -24,7 +39,7 @@ func writeField(f field, buffer *bytes.Buffer) { } } -// tagOrder true if tag i should occur before tag j +// tagOrder true if tag i should occur before tag j. type tagOrder func(i, j Tag) bool type tagSort struct { @@ -43,7 +58,7 @@ type FieldMap struct { rwLock *sync.RWMutex } -// ascending tags +// ascending tags. func normalFieldOrder(i, j Tag) bool { return i < j } func (m *FieldMap) init() { @@ -56,7 +71,7 @@ func (m *FieldMap) initWithOrdering(ordering tagOrder) { m.compare = ordering } -// Tags returns all of the Field Tags in this FieldMap +// Tags returns all of the Field Tags in this FieldMap. func (m FieldMap) Tags() []Tag { m.rwLock.RLock() defer m.rwLock.RUnlock() @@ -74,7 +89,7 @@ func (m FieldMap) Get(parser Field) MessageRejectError { return m.GetField(parser.Tag(), parser) } -// Has returns true if the Tag is present in this FieldMap +// Has returns true if the Tag is present in this FieldMap. func (m FieldMap) Has(tag Tag) bool { m.rwLock.RLock() defer m.rwLock.RUnlock() @@ -100,7 +115,7 @@ func (m FieldMap) GetField(tag Tag, parser FieldValueReader) MessageRejectError return nil } -// GetBytes is a zero-copy GetField wrapper for []bytes fields +// GetBytes is a zero-copy GetField wrapper for []bytes fields. func (m FieldMap) GetBytes(tag Tag) ([]byte, MessageRejectError) { m.rwLock.RLock() defer m.rwLock.RUnlock() @@ -113,7 +128,7 @@ func (m FieldMap) GetBytes(tag Tag) ([]byte, MessageRejectError) { return f[0].value, nil } -// GetBool is a GetField wrapper for bool fields +// GetBool is a GetField wrapper for bool fields. func (m FieldMap) GetBool(tag Tag) (bool, MessageRejectError) { var val FIXBoolean if err := m.GetField(tag, &val); err != nil { @@ -122,7 +137,7 @@ func (m FieldMap) GetBool(tag Tag) (bool, MessageRejectError) { return bool(val), nil } -// GetInt is a GetField wrapper for int fields +// GetInt is a GetField wrapper for int fields. func (m FieldMap) GetInt(tag Tag) (int, MessageRejectError) { bytes, err := m.GetBytes(tag) if err != nil { @@ -137,7 +152,7 @@ func (m FieldMap) GetInt(tag Tag) (int, MessageRejectError) { return int(val), err } -// GetTime is a GetField wrapper for utc timestamp fields +// GetTime is a GetField wrapper for utc timestamp fields. func (m FieldMap) GetTime(tag Tag) (t time.Time, err MessageRejectError) { m.rwLock.RLock() defer m.rwLock.RUnlock() @@ -155,7 +170,7 @@ func (m FieldMap) GetTime(tag Tag) (t time.Time, err MessageRejectError) { return val.Time, err } -// GetString is a GetField wrapper for string fields +// GetString is a GetField wrapper for string fields. func (m FieldMap) GetString(tag Tag) (string, MessageRejectError) { var val FIXString if err := m.GetField(tag, &val); err != nil { @@ -184,35 +199,35 @@ func (m FieldMap) GetGroup(parser FieldGroupReader) MessageRejectError { return nil } -// SetField sets the field with Tag tag +// SetField sets the field with Tag tag. func (m *FieldMap) SetField(tag Tag, field FieldValueWriter) *FieldMap { return m.SetBytes(tag, field.Write()) } -// SetBytes sets bytes +// SetBytes sets bytes. func (m *FieldMap) SetBytes(tag Tag, value []byte) *FieldMap { f := m.getOrCreate(tag) initField(f, tag, value) return m } -// SetBool is a SetField wrapper for bool fields +// SetBool is a SetField wrapper for bool fields. func (m *FieldMap) SetBool(tag Tag, value bool) *FieldMap { return m.SetField(tag, FIXBoolean(value)) } -// SetInt is a SetField wrapper for int fields +// SetInt is a SetField wrapper for int fields. func (m *FieldMap) SetInt(tag Tag, value int) *FieldMap { v := FIXInt(value) return m.SetBytes(tag, v.Write()) } -// SetString is a SetField wrapper for string fields +// SetString is a SetField wrapper for string fields. func (m *FieldMap) SetString(tag Tag, value string) *FieldMap { return m.SetBytes(tag, []byte(value)) } -// Clear purges all fields from field map +// Clear purges all fields from field map. func (m *FieldMap) Clear() { m.rwLock.Lock() defer m.rwLock.Unlock() @@ -223,7 +238,7 @@ func (m *FieldMap) Clear() { } } -// CopyInto overwrites the given FieldMap with this one +// CopyInto overwrites the given FieldMap with this one. func (m *FieldMap) CopyInto(to *FieldMap) { m.rwLock.RLock() defer m.rwLock.RUnlock() @@ -266,14 +281,14 @@ func (m *FieldMap) getOrCreate(tag Tag) field { return f } -// Set is a setter for fields +// Set is a setter for fields. func (m *FieldMap) Set(field FieldWriter) *FieldMap { f := m.getOrCreate(field.Tag()) initField(f, field.Tag(), field.Write()) return m } -// SetGroup is a setter specific to group fields +// SetGroup is a setter specific to group fields. func (m *FieldMap) SetGroup(field FieldGroupWriter) *FieldMap { m.rwLock.Lock() defer m.rwLock.Unlock() @@ -310,7 +325,7 @@ func (m FieldMap) total() int { for _, fields := range m.tagLookup { for _, tv := range fields { switch tv.tag { - case tagCheckSum: //tag does not contribute to total + case tagCheckSum: // Tag does not contribute to total. default: total += tv.total() } @@ -328,7 +343,7 @@ func (m FieldMap) length() int { for _, fields := range m.tagLookup { for _, tv := range fields { switch tv.tag { - case tagBeginString, tagBodyLength, tagCheckSum: //tags do not contribute to length + case tagBeginString, tagBodyLength, tagCheckSum: // Tags do not contribute to length. default: length += tv.length() } diff --git a/field_map_test.go b/field_map_test.go index f07f6f396..5d7da7041 100644 --- a/field_map_test.go +++ b/field_map_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/file_log.go b/file_log.go index 52146f07e..85eefab1d 100644 --- a/file_log.go +++ b/file_log.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/file_log_test.go b/file_log_test.go index 3358dc20a..b303ec290 100644 --- a/file_log_test.go +++ b/file_log_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/filestore.go b/filestore.go index 3b93db6e2..2a548cadb 100644 --- a/filestore.go +++ b/filestore.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -39,12 +54,12 @@ type fileStore struct { targetSeqNumsFile *os.File } -// NewFileStoreFactory returns a file-based implementation of MessageStoreFactory +// NewFileStoreFactory returns a file-based implementation of MessageStoreFactory. func NewFileStoreFactory(settings *Settings) MessageStoreFactory { return fileStoreFactory{settings: settings} } -// Create creates a new FileStore implementation of the MessageStore interface +// Create creates a new FileStore implementation of the MessageStore interface. func (f fileStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { @@ -82,7 +97,7 @@ func newFileStore(sessionID SessionID, dirname string) (*fileStore, error) { return store, nil } -// Reset deletes the store files and sets the seqnums back to 1 +// Reset deletes the store files and sets the seqnums back to 1. func (store *fileStore) Reset() error { if err := store.cache.Reset(); err != nil { return errors.Wrap(err, "cache reset") @@ -109,7 +124,7 @@ func (store *fileStore) Reset() error { return store.Refresh() } -// Refresh closes the store files and then reloads from them +// Refresh closes the store files and then reloads from them. func (store *fileStore) Refresh() (err error) { if err = store.cache.Reset(); err != nil { err = errors.Wrap(err, "cache reset") @@ -228,17 +243,17 @@ func (store *fileStore) setSeqNum(f *os.File, seqNum int) error { return nil } -// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent +// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent. func (store *fileStore) NextSenderMsgSeqNum() int { return store.cache.NextSenderMsgSeqNum() } -// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received +// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received. func (store *fileStore) NextTargetMsgSeqNum() int { return store.cache.NextTargetMsgSeqNum() } -// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent +// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent. func (store *fileStore) SetNextSenderMsgSeqNum(next int) error { if err := store.cache.SetNextSenderMsgSeqNum(next); err != nil { return errors.Wrap(err, "cache") @@ -246,7 +261,7 @@ func (store *fileStore) SetNextSenderMsgSeqNum(next int) error { return store.setSeqNum(store.senderSeqNumsFile, next) } -// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received +// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received. func (store *fileStore) SetNextTargetMsgSeqNum(next int) error { if err := store.cache.SetNextTargetMsgSeqNum(next); err != nil { return errors.Wrap(err, "cache") @@ -254,7 +269,7 @@ func (store *fileStore) SetNextTargetMsgSeqNum(next int) error { return store.setSeqNum(store.targetSeqNumsFile, next) } -// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent +// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent. func (store *fileStore) IncrNextSenderMsgSeqNum() error { if err := store.cache.IncrNextSenderMsgSeqNum(); err != nil { return errors.Wrap(err, "cache") @@ -262,7 +277,7 @@ func (store *fileStore) IncrNextSenderMsgSeqNum() error { return store.setSeqNum(store.senderSeqNumsFile, store.cache.NextSenderMsgSeqNum()) } -// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received +// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received. func (store *fileStore) IncrNextTargetMsgSeqNum() error { if err := store.cache.IncrNextTargetMsgSeqNum(); err != nil { return errors.Wrap(err, "cache") @@ -270,7 +285,7 @@ func (store *fileStore) IncrNextTargetMsgSeqNum() error { return store.setSeqNum(store.targetSeqNumsFile, store.cache.NextTargetMsgSeqNum()) } -// CreationTime returns the creation time of the store +// CreationTime returns the creation time of the store. func (store *fileStore) CreationTime() time.Time { return store.cache.CreationTime() } @@ -337,7 +352,7 @@ func (store *fileStore) GetMessages(beginSeqNum, endSeqNum int) ([][]byte, error return msgs, nil } -// Close closes the store's files +// Close closes the store's files. func (store *fileStore) Close() error { if err := closeFile(store.bodyFile); err != nil { return err diff --git a/filestore_test.go b/filestore_test.go index 56fc8ec68..3713ac8a9 100644 --- a/filestore_test.go +++ b/filestore_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -12,7 +27,7 @@ import ( "github.com/stretchr/testify/suite" ) -// FileStoreTestSuite runs all tests in the MessageStoreTestSuite against the FileStore implementation +// FileStoreTestSuite runs all tests in the MessageStoreTestSuite against the FileStore implementation. type FileStoreTestSuite struct { MessageStoreTestSuite fileStoreRootPath string diff --git a/fileutil.go b/fileutil.go index 5334f271c..0698a3a97 100644 --- a/fileutil.go +++ b/fileutil.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -32,7 +47,7 @@ func sessionIDFilenamePrefix(s SessionID) string { return strings.Join(fname, "-") } -// closeFile behaves like Close, except that no error is returned if the file does not exist +// closeFile behaves like Close, except that no error is returned if the file does not exist. func closeFile(f *os.File) error { if f != nil { if err := f.Close(); err != nil { @@ -44,7 +59,7 @@ func closeFile(f *os.File) error { return nil } -// removeFile behaves like os.Remove, except that no error is returned if the file does not exist +// removeFile behaves like os.Remove, except that no error is returned if the file does not exist. func removeFile(fname string) error { if err := os.Remove(fname); (err != nil) && !os.IsNotExist(err) { return errors.Wrapf(err, "remove %v", fname) @@ -52,7 +67,7 @@ func removeFile(fname string) error { return nil } -// openOrCreateFile opens a file for reading and writing, creating it if necessary +// openOrCreateFile opens a file for reading and writing, creating it if necessary. func openOrCreateFile(fname string, perm os.FileMode) (f *os.File, err error) { if f, err = os.OpenFile(fname, os.O_RDWR, perm); err != nil { if f, err = os.OpenFile(fname, os.O_RDWR|os.O_CREATE, perm); err != nil { diff --git a/fileutil_test.go b/fileutil_test.go index f634651df..0f9095364 100644 --- a/fileutil_test.go +++ b/fileutil_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_boolean.go b/fix_boolean.go index 2d9bc57fb..73e4fc168 100644 --- a/fix_boolean.go +++ b/fix_boolean.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -7,7 +22,7 @@ import ( // FIXBoolean is a FIX Boolean value, implements FieldValue. type FIXBoolean bool -// Bool converts the FIXBoolean value to bool +// Bool converts the FIXBoolean value to bool. func (f FIXBoolean) Bool() bool { return bool(f) } func (f *FIXBoolean) Read(bytes []byte) error { diff --git a/fix_boolean_test.go b/fix_boolean_test.go index 150d8c0d6..c02747834 100644 --- a/fix_boolean_test.go +++ b/fix_boolean_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_bytes.go b/fix_bytes.go index 8fb14d1a9..b998843c3 100644 --- a/fix_bytes.go +++ b/fix_bytes.go @@ -1,6 +1,21 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix -// FIXBytes is a generic FIX field value, implements FieldValue. Enables zero copy read from a FieldMap +// FIXBytes is a generic FIX field value, implements FieldValue. Enables zero copy read from a FieldMap. type FIXBytes []byte func (f *FIXBytes) Read(bytes []byte) (err error) { diff --git a/fix_bytes_test.go b/fix_bytes_test.go index 4dc94b56b..0855bdd16 100644 --- a/fix_bytes_test.go +++ b/fix_bytes_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_decimal.go b/fix_decimal.go index 143e69d7a..a435c79fc 100644 --- a/fix_decimal.go +++ b/fix_decimal.go @@ -1,12 +1,27 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/shopspring/decimal" -// FIXDecimal is a FIX Float Value that implements an arbitrary precision fixed-point decimal. Implements FieldValue +// FIXDecimal is a FIX Float Value that implements an arbitrary precision fixed-point decimal. Implements FieldValue. type FIXDecimal struct { decimal.Decimal - //Scale is the number of digits after the decimal point when Writing the field value as a FIX value + // Scale is the number of digits after the decimal point when Writing the field value as a FIX value. Scale int32 } diff --git a/fix_decimal_test.go b/fix_decimal_test.go index 1785d6e67..f6fc3d53c 100644 --- a/fix_decimal_test.go +++ b/fix_decimal_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_float.go b/fix_float.go index 28cafa576..1d4b310c2 100644 --- a/fix_float.go +++ b/fix_float.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -5,10 +20,10 @@ import ( "strconv" ) -// FIXFloat is a FIX Float Value, implements FieldValue +// FIXFloat is a FIX Float Value, implements FieldValue. type FIXFloat float64 -// Float64 converts the FIXFloat value to float64 +// Float64 converts the FIXFloat value to float64. func (f FIXFloat) Float64() float64 { return float64(f) } func (f *FIXFloat) Read(bytes []byte) error { @@ -17,7 +32,7 @@ func (f *FIXFloat) Read(bytes []byte) error { return err } - //strconv allows values like "+100.00", which is not allowed for FIX float types + // `strconv` allows values like "+100.00", which is not allowed for FIX float types. for _, b := range bytes { if b != '.' && b != '-' && !isDecimal(b) { return fmt.Errorf("invalid value %v", string(bytes)) diff --git a/fix_float_test.go b/fix_float_test.go index b31bdbb60..6b75eaf11 100644 --- a/fix_float_test.go +++ b/fix_float_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_int.go b/fix_int.go index 645884b95..6bd968003 100644 --- a/fix_int.go +++ b/fix_int.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -6,10 +21,10 @@ import ( ) const ( - //- + // ASCII - char. asciiMinus = 45 - //ascii numbers 0-9 + // ASCII numbers 0-9. ascii0 = 48 ascii9 = 57 ) @@ -43,10 +58,10 @@ func parseUInt(d []byte) (n int, err error) { return } -// FIXInt is a FIX Int Value, implements FieldValue +// FIXInt is a FIX Int Value, implements FieldValue. type FIXInt int -// Int converts the FIXInt value to int +// Int converts the FIXInt value to int. func (f FIXInt) Int() int { return int(f) } func (f *FIXInt) Read(bytes []byte) error { diff --git a/fix_int_test.go b/fix_int_test.go index 64142c045..caa9b7840 100644 --- a/fix_int_test.go +++ b/fix_int_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_string.go b/fix_string.go index 39c2119a1..b4fe18a3d 100644 --- a/fix_string.go +++ b/fix_string.go @@ -1,6 +1,21 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix -// FIXString is a FIX String Value, implements FieldValue +// FIXString is a FIX String Value, implements FieldValue. type FIXString string func (f FIXString) String() string { diff --git a/fix_string_test.go b/fix_string_test.go index f2672f39e..c17a69d3c 100644 --- a/fix_string_test.go +++ b/fix_string_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/fix_utc_timestamp.go b/fix_utc_timestamp.go index c6b685ca3..ebd40cb06 100644 --- a/fix_utc_timestamp.go +++ b/fix_utc_timestamp.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -5,10 +20,10 @@ import ( "time" ) -// TimestampPrecision defines the precision used by FIXUTCTimestamp +// TimestampPrecision defines the precision used by FIXUTCTimestamp. type TimestampPrecision int -// All TimestampPrecisions supported by FIX +// All TimestampPrecisions supported by FIX. const ( Millis TimestampPrecision = iota Seconds @@ -16,7 +31,7 @@ const ( Nanos ) -// FIXUTCTimestamp is a FIX UTC Timestamp value, implements FieldValue +// FIXUTCTimestamp is a FIX UTC Timestamp value, implements FieldValue. type FIXUTCTimestamp struct { time.Time Precision TimestampPrecision @@ -31,12 +46,12 @@ const ( func (f *FIXUTCTimestamp) Read(bytes []byte) (err error) { switch len(bytes) { - //seconds + // Seconds. case 17: f.Time, err = time.Parse(utcTimestampSecondsFormat, string(bytes)) f.Precision = Seconds - //millis + // Millis. case 21: f.Time, err = time.Parse(utcTimestampMillisFormat, string(bytes)) f.Precision = Millis diff --git a/fix_utc_timestamp_test.go b/fix_utc_timestamp_test.go index b29039587..da2d0ecb9 100644 --- a/fix_utc_timestamp_test.go +++ b/fix_utc_timestamp_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix_test import ( diff --git a/in_session.go b/in_session.go index 3ca45d7bd..663e115a5 100644 --- a/in_session.go +++ b/in_session.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -145,7 +160,7 @@ func (state inSession) handleSequenceReset(session *session, msg *Message) (next return handleStateError(session, err) } case newSeqNo < expectedSeqNum: - //FIXME: to be compliant with legacy tests, do not include tag in reftagid? (11c_NewSeqNoLess) + // FIXME: to be compliant with legacy tests, do not include tag in reftagid? (11c_NewSeqNoLess). if err := session.doReject(msg, valueIsIncorrectNoTag()); err != nil { return handleStateError(session, err) } @@ -261,7 +276,7 @@ func (state inSession) processReject(session *session, msg *Message, rej Message var nextState resendState switch currentState := session.State.(type) { case resendState: - //assumes target too high reject already sent + // Assumes target too high reject already sent. nextState = currentState default: var err error @@ -275,7 +290,7 @@ func (state inSession) processReject(session *session, msg *Message, rej Message } nextState.messageStash[TypedError.ReceivedTarget] = msg - //do not reclaim stashed message + // Do not reclaim stashed message. msg.keepMessage = true return nextState diff --git a/in_session_test.go b/in_session_test.go index 80e827dec..aa9f87084 100644 --- a/in_session_test.go +++ b/in_session_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -318,7 +333,7 @@ func (s *InSessionTestSuite) TestFIXMsgInResendRequestDoNotSendApp() { s.MockApp.AssertNumberOfCalls(s.T(), "ToApp", 1) s.NextSenderMsgSeqNum(4) - //NOTE: a cheat here, need to reset mock + // NOTE: a cheat here, need to reset mock. s.MockApp = MockApp{} s.MockApp.On("FromAdmin").Return(nil) s.MockApp.On("ToApp").Return(ErrDoNotSend) diff --git a/initiator.go b/initiator.go index 8426c7f26..a3d64afc3 100644 --- a/initiator.go +++ b/initiator.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -29,7 +44,7 @@ func (i *Initiator) Start() (err error) { i.stopChan = make(chan interface{}) for sessionID, settings := range i.sessionSettings { - //TODO: move into session factory + // TODO: move into session factory. var tlsConfig *tls.Config if tlsConfig, err = loadTLSConfig(settings); err != nil { return @@ -54,7 +69,7 @@ func (i *Initiator) Start() (err error) { func (i *Initiator) Stop() { select { case <-i.stopChan: - //closed already + // Closed already. return default: } @@ -92,7 +107,7 @@ func NewInitiator(app Application, storeFactory MessageStoreFactory, appSettings return i, nil } -// waitForInSessionTime returns true if the session is in session, false if the handler should stop +// waitForInSessionTime returns true if the session is in session, false if the handler should stop. func (i *Initiator) waitForInSessionTime(session *session) bool { inSessionTime := make(chan interface{}) go func() { @@ -109,7 +124,7 @@ func (i *Initiator) waitForInSessionTime(session *session) bool { return true } -// waitForReconnectInterval returns true if a reconnect should be re-attempted, false if handler should stop +// waitForReconnectInterval returns true if a reconnect should be re-attempted, false if handler should stop. func (i *Initiator) waitForReconnectInterval(reconnectInterval time.Duration) bool { select { case <-time.After(reconnectInterval): diff --git a/internal/event.go b/internal/event.go index 7e00cc2b8..f737050d8 100644 --- a/internal/event.go +++ b/internal/event.go @@ -1,15 +1,15 @@ package internal -// Event is an abstraction for session events +// Event is an abstraction for session events. type Event int const ( - //PeerTimeout indicates the session peer has become unresponsive + // PeerTimeout indicates the session peer has become unresponsive. PeerTimeout Event = iota - //NeedHeartbeat indicates the session should send a heartbeat + // NeedHeartbeat indicates the session should send a heartbeat. NeedHeartbeat - //LogonTimeout indicates the peer has not sent a logon request + // LogonTimeout indicates the peer has not sent a logon request. LogonTimeout - //LogoutTimeout indicates the peer has not sent a logout request + // LogoutTimeout indicates the peer has not sent a logout request. LogoutTimeout ) diff --git a/internal/session_settings.go b/internal/session_settings.go index b91d89a0d..e003f54e4 100644 --- a/internal/session_settings.go +++ b/internal/session_settings.go @@ -2,7 +2,7 @@ package internal import "time" -// SessionSettings stores all of the configuration for a given session +// SessionSettings stores all of the configuration for a given session. type SessionSettings struct { ResetOnLogon bool RefreshOnLogon bool @@ -18,10 +18,10 @@ type SessionSettings struct { MaxLatency time.Duration DisableMessagePersist bool - //required on logon for FIX.T.1 messages + // Required on logon for FIX.T.1 messages. DefaultApplVerID string - //specific to initiators + // Specific to initiators. ReconnectInterval time.Duration LogoutTimeout time.Duration LogonTimeout time.Duration diff --git a/internal/time_range.go b/internal/time_range.go index 4b7f9d7c7..7c2ef10f6 100644 --- a/internal/time_range.go +++ b/internal/time_range.go @@ -6,7 +6,7 @@ import ( "github.com/pkg/errors" ) -// TimeOfDay represents the time of day +// TimeOfDay represents the time of day. type TimeOfDay struct { hour, minute, second int d time.Duration @@ -14,7 +14,7 @@ type TimeOfDay struct { const shortForm = "15:04:05" -// NewTimeOfDay returns a newly initialized TimeOfDay +// NewTimeOfDay returns a newly initialized TimeOfDay. func NewTimeOfDay(hour, minute, second int) TimeOfDay { d := time.Duration(second)*time.Second + time.Duration(minute)*time.Minute + @@ -23,7 +23,7 @@ func NewTimeOfDay(hour, minute, second int) TimeOfDay { return TimeOfDay{hour: hour, minute: minute, second: second, d: d} } -// ParseTimeOfDay parses a TimeOfDay from a string in the format HH:MM:SS +// ParseTimeOfDay parses a TimeOfDay from a string in the format HH:MM:SS. func ParseTimeOfDay(str string) (TimeOfDay, error) { t, err := time.Parse(shortForm, str) if err != nil { @@ -33,19 +33,19 @@ func ParseTimeOfDay(str string) (TimeOfDay, error) { return NewTimeOfDay(t.Clock()), nil } -// TimeRange represents a time band in a given time zone +// TimeRange represents a time band in a given time zone. type TimeRange struct { startTime, endTime TimeOfDay startDay, endDay *time.Weekday loc *time.Location } -// NewUTCTimeRange returns a time range in UTC +// NewUTCTimeRange returns a time range in UTC. func NewUTCTimeRange(start, end TimeOfDay) *TimeRange { return NewTimeRangeInLocation(start, end, time.UTC) } -// NewTimeRangeInLocation returns a time range in a given location +// NewTimeRangeInLocation returns a time range in a given location. func NewTimeRangeInLocation(start, end TimeOfDay, loc *time.Location) *TimeRange { if loc == nil { panic("time: missing Location in call to NewTimeRangeInLocation") @@ -54,12 +54,12 @@ func NewTimeRangeInLocation(start, end TimeOfDay, loc *time.Location) *TimeRange return &TimeRange{startTime: start, endTime: end, loc: loc} } -// NewUTCWeekRange returns a weekly TimeRange +// NewUTCWeekRange returns a weekly TimeRange. func NewUTCWeekRange(startTime, endTime TimeOfDay, startDay, endDay time.Weekday) *TimeRange { return NewWeekRangeInLocation(startTime, endTime, startDay, endDay, time.UTC) } -// NewWeekRangeInLocation returns a time range in a given location +// NewWeekRangeInLocation returns a time range in a given location. func NewWeekRangeInLocation(startTime, endTime TimeOfDay, startDay, endDay time.Weekday, loc *time.Location) *TimeRange { r := NewTimeRangeInLocation(startTime, endTime, loc) r.startDay = &startDay @@ -120,7 +120,7 @@ func (r *TimeRange) isInWeekRange(t time.Time) bool { return true } -// IsInRange returns true if time t is within in the time range +// IsInRange returns true if time t is within in the time range. func (r *TimeRange) IsInRange(t time.Time) bool { if r == nil { return true @@ -133,7 +133,7 @@ func (r *TimeRange) IsInRange(t time.Time) bool { return r.isInTimeRange(t) } -// IsInSameRange determines if two points in time are in the same time range +// IsInSameRange determines if two points in time are in the same time range. func (r *TimeRange) IsInSameRange(t1, t2 time.Time) bool { if r == nil { return true diff --git a/latent_state.go b/latent_state.go index e6e5bece4..133509c7b 100644 --- a/latent_state.go +++ b/latent_state.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/quickfixgo/quickfix/internal" diff --git a/latent_state_test.go b/latent_state_test.go index db6e925b6..e3379a4e8 100644 --- a/latent_state_test.go +++ b/latent_state_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/log.go b/log.go index d346a5d7a..dbf6726fc 100644 --- a/log.go +++ b/log.go @@ -1,25 +1,40 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix // Log is a generic interface for logging FIX messages and events. type Log interface { - //OnIncoming log incoming fix message + // OnIncoming log incoming fix message. OnIncoming([]byte) - //OnOutgoing log outgoing fix message + // OnOutgoing log outgoing fix message. OnOutgoing([]byte) - //OnEvent log fix event + // OnEvent log fix event. OnEvent(string) - //OnEventf log fix event according to format specifier + // OnEventf log fix event according to format specifier. OnEventf(string, ...interface{}) } -// The LogFactory interface creates global and session specific Log instances +// The LogFactory interface creates global and session specific Log instances. type LogFactory interface { - //Create global log + // Create global log. Create() (Log, error) - //CreateSessionLog session specific log + // CreateSessionLog session specific log. CreateSessionLog(sessionID SessionID) (Log, error) } diff --git a/logon_state.go b/logon_state.go index d254b92b3..05c970838 100644 --- a/logon_state.go +++ b/logon_state.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/logon_state_test.go b/logon_state_test.go index cea45618b..96afc2e90 100644 --- a/logon_state_test.go +++ b/logon_state_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -83,7 +98,7 @@ func (s *LogonStateTestSuite) TestFixMsgInLogon() { s.MockApp.AssertExpectations(s.T()) s.State(inSession{}) - s.Equal(32*time.Second, s.session.HeartBtInt) //should be written from logon message + s.Equal(32*time.Second, s.session.HeartBtInt) // Should be written from logon message. s.False(s.session.HeartBtIntOverride) s.LastToAdminMessageSent() @@ -112,7 +127,7 @@ func (s *LogonStateTestSuite) TestFixMsgInLogonHeartBtIntOverride() { s.MockApp.AssertExpectations(s.T()) s.State(inSession{}) - s.Equal(time.Second, s.session.HeartBtInt) //should not have changed + s.Equal(time.Second, s.session.HeartBtInt) // Should not have changed. s.True(s.session.HeartBtIntOverride) s.LastToAdminMessageSent() @@ -309,7 +324,7 @@ func (s *LogonStateTestSuite) TestFixMsgInLogonSeqNumTooHigh() { s.State(resendState{}) s.NextTargetMsgSeqNum(1) - //session should send logon, and then queues resend request for send + // Session should send logon, and then queues resend request for send. s.MockApp.AssertNumberOfCalls(s.T(), "ToAdmin", 2) msgBytesSent, ok := s.Receiver.LastMessage() s.Require().True(ok) diff --git a/logout_state.go b/logout_state.go index 071512ce1..cee8e9bd8 100644 --- a/logout_state.go +++ b/logout_state.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/quickfixgo/quickfix/internal" diff --git a/logout_state_test.go b/logout_state_test.go index 5b074f329..f414bc85f 100644 --- a/logout_state_test.go +++ b/logout_state_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/message.go b/message.go index 0a637346b..74294f07c 100644 --- a/message.go +++ b/message.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -9,10 +24,10 @@ import ( "github.com/quickfixgo/quickfix/datadictionary" ) -// Header is first section of a FIX Message +// Header is first section of a FIX Message. type Header struct{ FieldMap } -// in the message header, the first 3 tags in the message header must be 8,9,35 +// in the message header, the first 3 tags in the message header must be 8,9,35. func headerFieldOrdering(i, j Tag) bool { var ordering = func(t Tag) uint32 { switch t { @@ -40,23 +55,23 @@ func headerFieldOrdering(i, j Tag) bool { return i < j } -// Init initializes the Header instance +// Init initializes the Header instance. func (h *Header) Init() { h.initWithOrdering(headerFieldOrdering) } -// Body is the primary application section of a FIX message +// Body is the primary application section of a FIX message. type Body struct{ FieldMap } -// Init initializes the FIX message +// Init initializes the FIX message. func (b *Body) Init() { b.init() } -// Trailer is the last section of a FIX message +// Trailer is the last section of a FIX message. type Trailer struct{ FieldMap } -// In the trailer, CheckSum (tag 10) must be last +// In the trailer, CheckSum (tag 10) must be last. func trailerFieldOrdering(i, j Tag) bool { switch { case i == tagCheckSum: @@ -68,7 +83,7 @@ func trailerFieldOrdering(i, j Tag) bool { return i < j } -// Init initializes the FIX message +// Init initializes the FIX message. func (t *Trailer) Init() { t.initWithOrdering(trailerFieldOrdering) } @@ -79,22 +94,22 @@ type Message struct { Trailer Trailer Body Body - //ReceiveTime is the time that this message was read from the socket connection + // ReceiveTime is the time that this message was read from the socket connection. ReceiveTime time.Time rawMessage *bytes.Buffer - //slice of Bytes corresponding to the message body + // Slice of Bytes corresponding to the message body. bodyBytes []byte - //field bytes as they appear in the raw message + // Field bytes as they appear in the raw message. fields []TagValue - //flag is true if this message should not be returned to pool after use + // Flag is true if this message should not be returned to pool after use. keepMessage bool } -// ToMessage returns the message itself +// ToMessage returns the message itself. func (m *Message) ToMessage() *Message { return m } // parseError is returned when bytes cannot be parsed as a FIX message. @@ -104,7 +119,7 @@ type parseError struct { func (e parseError) Error() string { return fmt.Sprintf("error parsing message: %s", e.OrigError) } -// NewMessage returns a newly initialized Message instance +// NewMessage returns a newly initialized Message instance. func NewMessage() *Message { m := new(Message) m.Header.Init() @@ -149,7 +164,7 @@ func ParseMessageWithDataDictionary( rawBytes := rawMessage.Bytes() - //allocate fields in one chunk + // Allocate fields in one chunk. fieldCount := 0 for _, b := range rawBytes { if b == '\001' { @@ -169,7 +184,7 @@ func ParseMessageWithDataDictionary( fieldIndex := 0 - //message must start with begin string, body length, msg type + // Message must start with begin string, body length, msg type. if rawBytes, err = extractSpecificField(&msg.fields[fieldIndex], tagBeginString, rawBytes); err != nil { return } @@ -223,7 +238,7 @@ func ParseMessageWithDataDictionary( fieldIndex++ } - //body length would only be larger than trailer if fields out of order + // Body length would only be larger than trailer if fields out of order. if len(msg.bodyBytes) > len(trailerBytes) { msg.bodyBytes = msg.bodyBytes[:len(msg.bodyBytes)-len(trailerBytes)] } @@ -231,7 +246,7 @@ func ParseMessageWithDataDictionary( length := 0 for _, field := range msg.fields { switch field.tag { - case tagBeginString, tagBodyLength, tagCheckSum: //tags do not contribute to length + case tagBeginString, tagBodyLength, tagCheckSum: // Tags do not contribute to length. default: length += field.length() } @@ -274,7 +289,7 @@ func isTrailerField(tag Tag, dataDict *datadictionary.DataDictionary) bool { return ok } -// MsgType returns MsgType (tag 35) field's value +// MsgType returns MsgType (tag 35) field's value. func (m *Message) MsgType() (string, MessageRejectError) { return m.Header.GetString(tagMsgType) } @@ -313,7 +328,7 @@ func (m *Message) reverseRoute() *Message { copy(tagDeliverToCompID, tagOnBehalfOfCompID) copy(tagDeliverToSubID, tagOnBehalfOfSubID) - //tags added in 4.1 + // Tags added in 4.1. var beginString FIXString if m.Header.GetField(tagBeginString, &beginString) == nil { if string(beginString) != BeginStringFIX40 { @@ -362,7 +377,7 @@ func formatCheckSum(value int) string { return fmt.Sprintf("%03d", value) } -// Build constructs a []byte from a Message instance +// Build constructs a []byte from a Message instance. func (m *Message) build() []byte { m.cook() diff --git a/message_router.go b/message_router.go index 03e57f867..c640f3e4d 100644 --- a/message_router.go +++ b/message_router.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix type routeKey struct { @@ -5,7 +20,7 @@ type routeKey struct { MsgType string } -// FIX ApplVerID string values +// FIX ApplVerID string values. const ( ApplVerIDFIX27 = "0" ApplVerIDFIX30 = "1" @@ -19,15 +34,15 @@ const ( ApplVerIDFIX50SP2 = "9" ) -// A MessageRoute is a function that can process a fromApp/fromAdmin callback +// A MessageRoute is a function that can process a fromApp/fromAdmin callback. type MessageRoute func(msg *Message, sessionID SessionID) MessageRejectError -// A MessageRouter is a mutex for MessageRoutes +// A MessageRouter is a mutex for MessageRoutes. type MessageRouter struct { routes map[routeKey]MessageRoute } -// NewMessageRouter returns an initialized MessageRouter instance +// NewMessageRouter returns an initialized MessageRouter instance. func NewMessageRouter() *MessageRouter { return &MessageRouter{routes: make(map[routeKey]MessageRoute)} } diff --git a/message_router_test.go b/message_router_test.go index 93779b464..b2e7b59f5 100644 --- a/message_router_test.go +++ b/message_router_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/message_test.go b/message_test.go index 40b063ca1..97a8f3f05 100644 --- a/message_test.go +++ b/message_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -83,7 +98,7 @@ func (s *MessageSuite) TestParseMessageWithDataDictionary() { } func (s *MessageSuite) TestParseOutOfOrder() { - //allow fields out of order, save for validation + // 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") s.Nil(ParseMessage(s.msg, rawMsg)) } @@ -159,7 +174,7 @@ func (s *MessageSuite) TestReverseRouteIgnoreEmpty() { } func (s *MessageSuite) TestReverseRouteFIX40() { - //onbehalfof/deliverto location id not supported in fix 4.0 + // The onbehalfof/deliverto location id not supported in fix 4.0. s.Nil(ParseMessage(s.msg, bytes.NewBufferString("8=FIX.4.09=17135=D34=249=TW50=KK52=20060102-15:04:0556=ISLD57=AP144=BB115=JCD116=CS128=MG129=CB142=JV143=RY145=BH11=ID21=338=10040=w54=155=INTC60=20060102-15:04:0510=123"))) builder := s.msg.reverseRoute() diff --git a/mongostore.go b/mongostore.go index 1bd32db7f..c9bc37ac2 100644 --- a/mongostore.go +++ b/mongostore.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -30,12 +45,12 @@ type mongoStore struct { allowTransactions bool } -// NewMongoStoreFactory returns a mongo-based implementation of MessageStoreFactory +// NewMongoStoreFactory returns a mongo-based implementation of MessageStoreFactory. func NewMongoStoreFactory(settings *Settings) MessageStoreFactory { return NewMongoStoreFactoryPrefixed(settings, "") } -// NewMongoStoreFactoryPrefixed returns a mongo-based implementation of MessageStoreFactory, with prefix on collections +// NewMongoStoreFactoryPrefixed returns a mongo-based implementation of MessageStoreFactory, with prefix on collections. func NewMongoStoreFactoryPrefixed(settings *Settings, collectionsPrefix string) MessageStoreFactory { return mongoStoreFactory{ settings: settings, @@ -44,7 +59,7 @@ func NewMongoStoreFactoryPrefixed(settings *Settings, collectionsPrefix string) } } -// Create creates a new MongoStore implementation of the MessageStore interface +// Create creates a new MongoStore implementation of the MessageStore interface. func (f mongoStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { @@ -109,14 +124,14 @@ func generateMessageFilter(s *SessionID) (messageFilter *mongoQuickFixEntryData) } type mongoQuickFixEntryData struct { - //Message specific data + // Message specific data. Msgseq int `bson:"msgseq,omitempty"` Message []byte `bson:"message,omitempty"` - //Session specific data + // Session specific data. CreationTime time.Time `bson:"creation_time,omitempty"` IncomingSeqNum int `bson:"incoming_seq_num,omitempty"` OutgoingSeqNum int `bson:"outgoing_seq_num,omitempty"` - //Indexed data + // Indexed data. BeginString string `bson:"begin_string"` SessionQualifier string `bson:"session_qualifier"` SenderCompID string `bson:"sender_comp_id"` @@ -127,7 +142,7 @@ type mongoQuickFixEntryData struct { TargetLocID string `bson:"target_loc_id"` } -// Reset deletes the store records and sets the seqnums back to 1 +// Reset deletes the store records and sets the seqnums back to 1. func (store *mongoStore) Reset() error { msgFilter := generateMessageFilter(&store.sessionID) _, err := store.db.Database(store.mongoDatabase).Collection(store.messagesCollection).DeleteMany(context.Background(), msgFilter) @@ -149,7 +164,7 @@ func (store *mongoStore) Reset() error { return err } -// Refresh reloads the store from the database +// Refresh reloads the store from the database. func (store *mongoStore) Refresh() error { if err := store.cache.Reset(); err != nil { return err @@ -194,17 +209,17 @@ func (store *mongoStore) populateCache() error { return nil } -// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent +// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent. func (store *mongoStore) NextSenderMsgSeqNum() int { return store.cache.NextSenderMsgSeqNum() } -// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received +// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received. func (store *mongoStore) NextTargetMsgSeqNum() int { return store.cache.NextTargetMsgSeqNum() } -// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent +// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent. func (store *mongoStore) SetNextSenderMsgSeqNum(next int) error { msgFilter := generateMessageFilter(&store.sessionID) sessionUpdate := generateMessageFilter(&store.sessionID) @@ -217,7 +232,7 @@ func (store *mongoStore) SetNextSenderMsgSeqNum(next int) error { return store.cache.SetNextSenderMsgSeqNum(next) } -// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received +// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received. func (store *mongoStore) SetNextTargetMsgSeqNum(next int) error { msgFilter := generateMessageFilter(&store.sessionID) sessionUpdate := generateMessageFilter(&store.sessionID) @@ -230,7 +245,7 @@ func (store *mongoStore) SetNextTargetMsgSeqNum(next int) error { return store.cache.SetNextTargetMsgSeqNum(next) } -// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent +// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent. func (store *mongoStore) IncrNextSenderMsgSeqNum() error { if err := store.cache.IncrNextSenderMsgSeqNum(); err != nil { return errors.Wrap(err, "cache incr") @@ -238,7 +253,7 @@ func (store *mongoStore) IncrNextSenderMsgSeqNum() error { return store.SetNextSenderMsgSeqNum(store.cache.NextSenderMsgSeqNum()) } -// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received +// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received. func (store *mongoStore) IncrNextTargetMsgSeqNum() error { if err := store.cache.IncrNextTargetMsgSeqNum(); err != nil { return errors.Wrap(err, "cache incr") @@ -246,7 +261,7 @@ func (store *mongoStore) IncrNextTargetMsgSeqNum() error { return store.SetNextTargetMsgSeqNum(store.cache.NextTargetMsgSeqNum()) } -// CreationTime returns the creation time of the store +// CreationTime returns the creation time of the store. func (store *mongoStore) CreationTime() time.Time { return store.cache.CreationTime() } @@ -307,7 +322,7 @@ func (store *mongoStore) SaveMessageAndIncrNextSenderMsgSeqNum(seqNum int, msg [ func (store *mongoStore) GetMessages(beginSeqNum, endSeqNum int) (msgs [][]byte, err error) { msgFilter := generateMessageFilter(&store.sessionID) - //Marshal into database form + // Marshal into database form. msgFilterBytes, err := bson.Marshal(msgFilter) if err != nil { return @@ -317,7 +332,7 @@ func (store *mongoStore) GetMessages(beginSeqNum, endSeqNum int) (msgs [][]byte, if err != nil { return } - //Modify the query to use a range for the sequence filter + // Modify the query to use a range for the sequence filter. seqFilter["msgseq"] = bson.M{ "$gte": beginSeqNum, "$lte": endSeqNum, @@ -339,7 +354,7 @@ func (store *mongoStore) GetMessages(beginSeqNum, endSeqNum int) (msgs [][]byte, return } -// Close closes the store's database connection +// Close closes the store's database connection. func (store *mongoStore) Close() error { if store.db != nil { err := store.db.Disconnect(context.Background()) diff --git a/mongostore_test.go b/mongostore_test.go index 32682b65d..4a8089f1c 100644 --- a/mongostore_test.go +++ b/mongostore_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -11,7 +26,7 @@ import ( "github.com/stretchr/testify/suite" ) -// MongoStoreTestSuite runs all tests in the MessageStoreTestSuite against the MongoStore implementation +// MongoStoreTestSuite runs all tests in the MessageStoreTestSuite against the MongoStore implementation. type MongoStoreTestSuite struct { MessageStoreTestSuite } diff --git a/msg_type.go b/msg_type.go index 309f302f4..823d9a752 100644 --- a/msg_type.go +++ b/msg_type.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "bytes" diff --git a/not_session_time.go b/not_session_time.go index 2e3b04c3d..058159b99 100644 --- a/not_session_time.go +++ b/not_session_time.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/quickfixgo/quickfix/internal" diff --git a/not_session_time_test.go b/not_session_time_test.go index 21a2c8f22..736e8efc9 100644 --- a/not_session_time_test.go +++ b/not_session_time_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/null_log.go b/null_log.go index 786271c42..106dcae42 100644 --- a/null_log.go +++ b/null_log.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix type nullLog struct{} diff --git a/parser.go b/parser.go index 13b992d03..a3ec73993 100644 --- a/parser.go +++ b/parser.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -12,7 +27,7 @@ const ( ) type parser struct { - //buffer is a slice of bigBuffer + // Buffer is a slice of bigBuffer. bigBuffer, buffer []byte reader io.Reader lastRead time.Time @@ -26,16 +41,16 @@ func (p *parser) readMore() (int, error) { if len(p.buffer) == cap(p.buffer) { var newBuffer []byte switch { - //initialize the parser + // Initialize the parser. case len(p.bigBuffer) == 0: p.bigBuffer = make([]byte, defaultBufSize) newBuffer = p.bigBuffer[0:0] - //shift buffer back to the start of bigBuffer + // Shift buffer back to the start of bigBuffer. case 2*len(p.buffer) <= len(p.bigBuffer): newBuffer = p.bigBuffer[0:len(p.buffer)] - //reallocate big buffer with enough space to shift buffer + // Reallocate big buffer with enough space to shift buffer. default: p.bigBuffer = make([]byte, 2*len(p.buffer)) newBuffer = p.bigBuffer[0:len(p.buffer)] diff --git a/parser_test.go b/parser_test.go index 533691986..34bca808d 100644 --- a/parser_test.go +++ b/parser_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/pending_timeout.go b/pending_timeout.go index 87154dddd..170af8a57 100644 --- a/pending_timeout.go +++ b/pending_timeout.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/quickfixgo/quickfix/internal" diff --git a/pending_timeout_test.go b/pending_timeout_test.go index 1ad845d89..954a79c7c 100644 --- a/pending_timeout_test.go +++ b/pending_timeout_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/quickfix_test.go b/quickfix_test.go index 575a28614..beb8792bc 100644 --- a/quickfix_test.go +++ b/quickfix_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -52,7 +67,7 @@ func (s *QuickFIXSuite) MessageEqualsBytes(expectedBytes []byte, msg *Message) { s.Equal(string(actualBytes), string(expectedBytes)) } -// MockStore wraps a memory store and mocks Refresh for convenience +// MockStore wraps a memory store and mocks Refresh for convenience. type MockStore struct { mock.Mock memoryStore diff --git a/registry.go b/registry.go index ffbcd1914..180bc8035 100644 --- a/registry.go +++ b/registry.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -10,12 +25,12 @@ var sessions = make(map[SessionID]*session) var errDuplicateSessionID = errors.New("Duplicate SessionID") var errUnknownSession = errors.New("Unknown session") -// Messagable is a Message or something that can be converted to a Message +// Messagable is a Message or something that can be converted to a Message. type Messagable interface { ToMessage() *Message } -// Send determines the session to send Messagable using header fields BeginString, TargetCompID, SenderCompID +// Send determines the session to send Messagable using header fields BeginString, TargetCompID, SenderCompID. func Send(m Messagable) (err error) { msg := m.ToMessage() var beginString FIXString @@ -39,7 +54,7 @@ func Send(m Messagable) (err error) { return SendToTarget(msg, sessionID) } -// SendToTarget sends a message based on the sessionID. Convenient for use in FromApp since it provides a session ID for incoming messages +// SendToTarget sends a message based on the sessionID. Convenient for use in FromApp since it provides a session ID for incoming messages. func SendToTarget(m Messagable, sessionID SessionID) error { msg := m.ToMessage() session, ok := lookupSession(sessionID) @@ -50,7 +65,7 @@ func SendToTarget(m Messagable, sessionID SessionID) error { return session.queueForSend(msg) } -// UnregisterSession removes a session from the set of known sessions +// UnregisterSession removes a session from the set of known sessions. func UnregisterSession(sessionID SessionID) error { sessionsLock.Lock() defer sessionsLock.Unlock() diff --git a/repeating_group.go b/repeating_group.go index 1cbbc8e2a..853cc7d35 100644 --- a/repeating_group.go +++ b/repeating_group.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -6,20 +21,20 @@ import ( "strconv" ) -// GroupItem interface is used to construct repeating group templates +// GroupItem interface is used to construct repeating group templates. type GroupItem interface { - //Tag returns the tag identifying this GroupItem + // Tag returns the tag identifying this GroupItem. Tag() Tag - //Read Parameter to Read is tagValues. For most fields, only the first tagValue will be required. - //The length of the slice extends from the tagValue mapped to the field to be read through the - //following fields. This can be useful for GroupItems made up of repeating groups. + // Read Parameter to Read is tagValues. For most fields, only the first tagValue will be required. + // The length of the slice extends from the tagValue mapped to the field to be read through the + // following fields. This can be useful for GroupItems made up of repeating groups. // - //The Read function returns the remaining tagValues not processed by the GroupItem. If there was a - //problem reading the field, an error may be returned + // The Read function returns the remaining tagValues not processed by the GroupItem. If there was a + // problem reading the field, an error may be returned. Read([]TagValue) ([]TagValue, error) - //Clone makes a copy of this GroupItem + // Clone makes a copy of this GroupItem. Clone() GroupItem } @@ -38,15 +53,15 @@ func (t protoGroupElement) Read(tv []TagValue) ([]TagValue, error) { func (t protoGroupElement) Clone() GroupItem { return t } -// GroupElement returns a GroupItem made up of a single field +// GroupElement returns a GroupItem made up of a single field. func GroupElement(tag Tag) GroupItem { return protoGroupElement{tag: tag} } -// GroupTemplate specifies the group item order for a RepeatingGroup +// GroupTemplate specifies the group item order for a RepeatingGroup. type GroupTemplate []GroupItem -// Clone makes a copy of this GroupTemplate +// Clone makes a copy of this GroupTemplate. func (gt GroupTemplate) Clone() GroupTemplate { clone := make(GroupTemplate, len(gt)) for i := range gt { @@ -56,17 +71,17 @@ func (gt GroupTemplate) Clone() GroupTemplate { return clone } -// Group is a group of fields occurring in a repeating group +// Group is a group of fields occurring in a repeating group. type Group struct{ FieldMap } -// RepeatingGroup is a FIX Repeating Group type +// RepeatingGroup is a FIX Repeating Group type. type RepeatingGroup struct { tag Tag template GroupTemplate groups []*Group } -// NewRepeatingGroup returns an initilized RepeatingGroup instance +// NewRepeatingGroup returns an initilized RepeatingGroup instance. func NewRepeatingGroup(tag Tag, template GroupTemplate) *RepeatingGroup { return &RepeatingGroup{ tag: tag, @@ -74,12 +89,12 @@ func NewRepeatingGroup(tag Tag, template GroupTemplate) *RepeatingGroup { } } -// Tag returns the Tag for this repeating Group +// Tag returns the Tag for this repeating Group. func (f RepeatingGroup) Tag() Tag { return f.tag } -// Clone makes a copy of this RepeatingGroup (tag, template) +// Clone makes a copy of this RepeatingGroup (tag, template). func (f RepeatingGroup) Clone() GroupItem { return &RepeatingGroup{ tag: f.tag, @@ -87,17 +102,17 @@ func (f RepeatingGroup) Clone() GroupItem { } } -// Len returns the number of Groups in this RepeatingGroup +// Len returns the number of Groups in this RepeatingGroup. func (f RepeatingGroup) Len() int { return len(f.groups) } -// Get returns the ith group in this RepeatingGroup +// Get returns the ith group in this RepeatingGroup. func (f RepeatingGroup) Get(i int) *Group { return f.groups[i] } -// Add appends a new group to the RepeatingGroup and returns the new Group +// Add appends a new group to the RepeatingGroup and returns the new Group. func (f *RepeatingGroup) Add() *Group { g := new(Group) g.initWithOrdering(f.groupTagOrder()) @@ -107,7 +122,7 @@ func (f *RepeatingGroup) Add() *Group { } // Write returns tagValues for all Items in the repeating group ordered by -// Group sequence and Group template order +// Group sequence and Group template order. func (f RepeatingGroup) Write() []TagValue { tvs := make([]TagValue, 1) tvs[0].init(f.tag, []byte(strconv.Itoa(len(f.groups)))) diff --git a/repeating_group_test.go b/repeating_group_test.go index 955e3b7da..abd316d78 100644 --- a/repeating_group_test.go +++ b/repeating_group_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/resend_state.go b/resend_state.go index d07559b82..8a46e36e3 100644 --- a/resend_state.go +++ b/resend_state.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "github.com/quickfixgo/quickfix/internal" @@ -17,8 +32,8 @@ func (s resendState) Timeout(session *session, event internal.Event) (nextState case inSession: nextState = s case pendingTimeout: - //wrap pendingTimeout in resend. prevents us falling back to inSession if recovering - //from pendingTimeout + // Wrap pendingTimeout in resend. prevents us falling back to inSession if recovering + // from pendingTimeout. nextState = pendingTimeout{s} } diff --git a/resend_state_test.go b/resend_state_test.go index 4d8184a9d..093660d85 100644 --- a/resend_state_test.go +++ b/resend_state_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -61,7 +76,7 @@ func (s *resendStateTestSuite) TestTimeoutUnchangedNeedHeartbeat() { func (s *resendStateTestSuite) TestFixMsgIn() { s.session.State = inSession{} - //in session expects seq number 1, send too high + // In session expects seq number 1, send too high. s.MessageFactory.SetNextSeqNum(2) s.MockApp.On("ToAdmin") @@ -98,7 +113,7 @@ func (s *resendStateTestSuite) TestFixMsgIn() { func (s *resendStateTestSuite) TestFixMsgInSequenceReset() { s.session.State = inSession{} - //in session expects seq number 1, send too high + // In session expects seq number 1, send too high. s.MessageFactory.SetNextSeqNum(3) s.MockApp.On("ToAdmin") @@ -130,7 +145,7 @@ func (s *resendStateTestSuite) TestFixMsgInResendChunk() { s.session.State = inSession{} s.ResendRequestChunkSize = 2 - //in session expects seq number 1, send too high + // In session expects seq number 1, send too high. s.MessageFactory.SetNextSeqNum(4) s.MockApp.On("ToAdmin") diff --git a/screen_log.go b/screen_log.go index e6271ecc0..c17d67ecb 100644 --- a/screen_log.go +++ b/screen_log.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/session.go b/session.go index f539d285a..e3a89b07c 100644 --- a/session.go +++ b/session.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -11,7 +26,7 @@ import ( "github.com/quickfixgo/quickfix/internal" ) -// The Session is the primary FIX abstraction for message communication +// The Session is the primary FIX abstraction for message communication. type session struct { store MessageStore @@ -21,10 +36,10 @@ type session struct { messageOut chan<- []byte messageIn <-chan fixIn - //application messages are queued up for send here + // Application messages are queued up for send here. toSend [][]byte - //mutex for access to toSend + // Mutex for access to toSend. sendMutex sync.Mutex sessionEvent chan internal.Event @@ -77,7 +92,7 @@ func (s *session) connect(msgIn <-chan fixIn, msgOut chan<- []byte) error { type stopReq struct{} func (s *session) stop() { - //stop once + // Stop once. s.stopOnce.Do(func() { s.admin <- stopReq{} }) @@ -208,7 +223,7 @@ func (s *session) resend(msg *Message) bool { return s.application.ToApp(msg, s.sessionID) == nil } -// queueForSend will validate, persist, and queue the message for send +// queueForSend will validate, persist, and queue the message for send. func (s *session) queueForSend(msg *Message) error { s.sendMutex.Lock() defer s.sendMutex.Unlock() @@ -228,7 +243,7 @@ func (s *session) queueForSend(msg *Message) error { return nil } -// send will validate, persist, queue the message. If the session is logged on, send all messages in the queue +// send will validate, persist, queue the message. If the session is logged on, send all messages in the queue. func (s *session) send(msg *Message) error { return s.sendInReplyTo(msg, nil) } @@ -251,7 +266,7 @@ func (s *session) sendInReplyTo(msg *Message, inReplyTo *Message) error { return nil } -// dropAndReset will drop the send queue and reset the message store +// dropAndReset will drop the send queue and reset the message store. func (s *session) dropAndReset() error { s.sendMutex.Lock() defer s.sendMutex.Unlock() @@ -396,7 +411,7 @@ func (s *session) sendResendRequest(beginSeq, endSeq int) (nextState resendState } func (s *session) handleLogon(msg *Message) error { - //Grab default app ver id from fixt.1.1 logon + // Grab default app ver id from fixt.1.1 logon. if s.sessionID.BeginString == BeginStringFIXT11 { var targetApplVerID FIXString @@ -642,7 +657,7 @@ func (s *session) doReject(msg *Message, rej MessageRejectError) error { default: reply.Body.SetField(tagSessionRejectReason, FIXInt(rej.RejectReason())) case rej.RejectReason() > rejectReasonInvalidMsgType && s.sessionID.BeginString == BeginStringFIX42: - //fix42 knows up to invalid msg type + // Fix42 knows up to invalid msg type. } if refTagID := rej.RefTagID(); refTagID != nil { @@ -743,14 +758,14 @@ func (s *session) run() { var stopChan = make(chan struct{}) s.stateTimer = internal.NewEventTimer(func() { select { - //deadlock in write to chan s.sessionEvent after s.Stopped()==true and end of loop session.go:766 because no reader of chan s.sessionEvent + // Deadlock in write to chan s.sessionEvent after s.Stopped()==true and end of loop session.go:766 because no reader of chan s.sessionEvent. case s.sessionEvent <- internal.NeedHeartbeat: case <-stopChan: } }) s.peerTimer = internal.NewEventTimer(func() { select { - //deadlock in write to chan s.sessionEvent after s.Stopped()==true and end of loop session.go:766 because no reader of chan s.sessionEvent + // Deadlock in write to chan s.sessionEvent after s.Stopped()==true and end of loop session.go:766 because no reader of chan s.sessionEvent. case s.sessionEvent <- internal.PeerTimeout: case <-stopChan: } diff --git a/session_factory.go b/session_factory.go index 769e5084a..3a6be68a5 100644 --- a/session_factory.go +++ b/session_factory.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -42,11 +57,11 @@ var applVerIDLookup = map[string]string{ } type sessionFactory struct { - //True if building sessions that initiate logon + // True if building sessions that initiate logon. BuildInitiators bool } -// Creates Session, associates with internal session registry +// Creates Session, associates with internal session registry. func (f sessionFactory) createSession( sessionID SessionID, storeFactory MessageStoreFactory, settings *SessionSettings, logFactory LogFactory, application Application, @@ -92,7 +107,7 @@ func (f sessionFactory) newSession( s.DefaultApplVerID = applVerID } - //If the transport or app data dictionary setting is set, the other also needs to be set. + // If the transport or app data dictionary setting is set, the other also needs to be set. if settings.HasSetting(config.TransportDataDictionary) || settings.HasSetting(config.AppDataDictionary) { var transportDataDictionaryPath, appDataDictionaryPath string if transportDataDictionaryPath, err = settings.Setting(config.TransportDataDictionary); err != nil { diff --git a/session_factory_test.go b/session_factory_test.go index a86cfe369..db99302f1 100644 --- a/session_factory_test.go +++ b/session_factory_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/session_id.go b/session_id.go index c3ce615fe..c4dfb3513 100644 --- a/session_id.go +++ b/session_id.go @@ -1,13 +1,28 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import "bytes" -// SessionID is a unique identifier of a Session +// SessionID is a unique identifier of a Session. type SessionID struct { BeginString, TargetCompID, TargetSubID, TargetLocationID, SenderCompID, SenderSubID, SenderLocationID, Qualifier string } -// IsFIXT returns true if the SessionID has a FIXT BeginString +// IsFIXT returns true if the SessionID has a FIXT BeginString. func (s SessionID) IsFIXT() bool { return s.BeginString == BeginStringFIXT11 } diff --git a/session_id_test.go b/session_id_test.go index 6c5eae3b2..3ea9a22e8 100644 --- a/session_id_test.go +++ b/session_id_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/session_rejects.go b/session_rejects.go index 2edfcd280..4ea16b61e 100644 --- a/session_rejects.go +++ b/session_rejects.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/session_settings.go b/session_settings.go index 49afbcd7f..323ac6234 100644 --- a/session_settings.go +++ b/session_settings.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -11,7 +26,7 @@ type SessionSettings struct { settings map[string]string } -// ConditionallyRequiredSetting indicates a missing setting +// ConditionallyRequiredSetting indicates a missing setting. type ConditionallyRequiredSetting struct { Setting string } @@ -20,7 +35,7 @@ func (e ConditionallyRequiredSetting) Error() string { return fmt.Sprintf("Conditionally Required Setting: %v", e.Setting) } -// IncorrectFormatForSetting indicates a setting that is incorrectly formatted +// IncorrectFormatForSetting indicates a setting that is incorrectly formatted. type IncorrectFormatForSetting struct { Setting, Value string Err error @@ -30,12 +45,12 @@ func (e IncorrectFormatForSetting) Error() string { return fmt.Sprintf("%q is invalid for %s", e.Value, e.Setting) } -// Init initializes or resets SessionSettings +// Init initializes or resets SessionSettings. func (s *SessionSettings) Init() { s.settings = make(map[string]string) } -// NewSessionSettings returns a newly initialized SessionSettings instance +// NewSessionSettings returns a newly initialized SessionSettings instance. func NewSessionSettings() *SessionSettings { s := &SessionSettings{} s.Init() @@ -45,7 +60,7 @@ func NewSessionSettings() *SessionSettings { // Set assigns a value to a setting on SessionSettings. func (s *SessionSettings) Set(setting string, val string) { - //lazy init + // Lazy init. if s.settings == nil { s.Init() } @@ -53,7 +68,7 @@ func (s *SessionSettings) Set(setting string, val string) { s.settings[setting] = val } -// HasSetting returns true if a setting is set, false if not +// HasSetting returns true if a setting is set, false if not. func (s *SessionSettings) HasSetting(setting string) bool { _, ok := s.settings[setting] return ok diff --git a/session_settings_test.go b/session_settings_test.go index 34687ae2c..7fa9a94ad 100644 --- a/session_settings_test.go +++ b/session_settings_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/session_state.go b/session_state.go index 016cb3e8c..230ac8613 100644 --- a/session_state.go +++ b/session_state.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -193,29 +208,29 @@ func handleStateError(s *session, err error) sessionState { // sessionState is the current state of the session state machine. The session state determines how the session responds to // incoming messages, timeouts, and requests to send application messages. type sessionState interface { - //FixMsgIn is called by the session on incoming messages from the counter party. The return type is the next session state - //following message processing + // FixMsgIn is called by the session on incoming messages from the counter party. + // The return type is the next session state following message processing. FixMsgIn(*session, *Message) (nextState sessionState) - //Timeout is called by the session on a timeout event. + // Timeout is called by the session on a timeout event. Timeout(*session, internal.Event) (nextState sessionState) - //IsLoggedOn returns true if state is logged on an in session, false otherwise + // IsLoggedOn returns true if state is logged on an in session, false otherwise. IsLoggedOn() bool - //IsConnected returns true if the state is connected + // IsConnected returns true if the state is connected. IsConnected() bool - //IsSessionTime returns true if the state is in session time + // IsSessionTime returns true if the state is in session time. IsSessionTime() bool - //ShutdownNow terminates the session state immediately + // ShutdownNow terminates the session state immediately. ShutdownNow(*session) - //Stop triggers a clean stop + // Stop triggers a clean stop. Stop(*session) (nextState sessionState) - //Stringer debugging convenience + // Stringer debugging convenience. fmt.Stringer } diff --git a/session_test.go b/session_test.go index 293b94805..457b5edd3 100644 --- a/session_test.go +++ b/session_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -70,7 +85,7 @@ func (s *SessionSuite) TestInsertSendingTime() { Precision TimestampPrecision ExpectedPrecision TimestampPrecision }{ - {BeginStringFIX40, Millis, Seconds}, //config is ignored for fix < 4.2 + {BeginStringFIX40, Millis, Seconds}, // Config is ignored for fix < 4.2. {BeginStringFIX41, Millis, Seconds}, {BeginStringFIX42, Millis, Millis}, @@ -170,7 +185,7 @@ func (s *SessionSuite) TestCheckTargetTooHigh() { s.Require().NotNil(err, "sequence number too high should return an error") s.IsType(targetTooHigh{}, err) - //spot on + // Spot on. msg.Header.SetField(tagMsgSeqNum, FIXInt(45)) s.Nil(s.session.checkTargetTooHigh(msg)) } @@ -217,13 +232,13 @@ func (s *SessionSuite) TestCheckTargetTooLow() { s.Require().NotNil(err, "sequence number is required") s.Equal(rejectReasonRequiredTagMissing, err.RejectReason()) - //too low + // Too low. msg.Header.SetField(tagMsgSeqNum, FIXInt(43)) err = s.session.checkTargetTooLow(msg) s.NotNil(err, "sequence number too low should return error") s.IsType(targetTooLow{}, err) - //spot on + // Spot on. msg.Header.SetField(tagMsgSeqNum, FIXInt(45)) s.Nil(s.session.checkTargetTooLow(msg)) } @@ -238,34 +253,34 @@ func (s *SessionSuite) TestShouldSendReset() { NextTargetMsgSeqNum int Expected bool }{ - {BeginStringFIX40, true, false, false, 1, 1, false}, //ResetSeqNumFlag not available < fix41 + {BeginStringFIX40, true, false, false, 1, 1, false}, // ResetSeqNumFlag not available < fix41. - {BeginStringFIX41, true, false, false, 1, 1, true}, //session must be configured to reset on logon + {BeginStringFIX41, true, false, false, 1, 1, true}, // Session must be configured to reset on logon. {BeginStringFIX42, true, false, false, 1, 1, true}, {BeginStringFIX43, true, false, false, 1, 1, true}, {BeginStringFIX44, true, false, false, 1, 1, true}, {BeginStringFIXT11, true, false, false, 1, 1, true}, - {BeginStringFIX41, false, true, false, 1, 1, true}, //or disconnect + {BeginStringFIX41, false, true, false, 1, 1, true}, // Or disconnect. {BeginStringFIX42, false, true, false, 1, 1, true}, {BeginStringFIX43, false, true, false, 1, 1, true}, {BeginStringFIX44, false, true, false, 1, 1, true}, {BeginStringFIXT11, false, true, false, 1, 1, true}, - {BeginStringFIX41, false, false, true, 1, 1, true}, //or logout + {BeginStringFIX41, false, false, true, 1, 1, true}, // Or logout. {BeginStringFIX42, false, false, true, 1, 1, true}, {BeginStringFIX43, false, false, true, 1, 1, true}, {BeginStringFIX44, false, false, true, 1, 1, true}, {BeginStringFIXT11, false, false, true, 1, 1, true}, - {BeginStringFIX41, true, true, false, 1, 1, true}, //or combo + {BeginStringFIX41, true, true, false, 1, 1, true}, // Or combo. {BeginStringFIX42, false, true, true, 1, 1, true}, {BeginStringFIX43, true, false, true, 1, 1, true}, {BeginStringFIX44, true, true, true, 1, 1, true}, - {BeginStringFIX41, false, false, false, 1, 1, false}, //or will not be set + {BeginStringFIX41, false, false, false, 1, 1, false}, // Or will not be set. - {BeginStringFIX41, true, false, false, 1, 10, false}, //session seq numbers should be reset at the time of check + {BeginStringFIX41, true, false, false, 1, 10, false}, // Session seq numbers should be reset at the time of check. {BeginStringFIX42, true, false, false, 2, 1, false}, {BeginStringFIX43, true, false, false, 14, 100, false}, } @@ -930,7 +945,7 @@ func (suite *SessionSendTestSuite) TestDropAndSendDropsQueue() { suite.MessageType(string(msgTypeLogon), msg) suite.FieldEquals(tagMsgSeqNum, 3, msg.Header) - //only one message sent + // Only one message sent. suite.LastToAdminMessageSent() suite.NoMessageSent() } @@ -952,7 +967,7 @@ func (suite *SessionSendTestSuite) TestDropAndSendDropsQueueWithReset() { suite.MessageType(string(msgTypeLogon), msg) suite.FieldEquals(tagMsgSeqNum, 1, msg.Header) - //only one message sent + // Only one message sent. suite.LastToAdminMessageSent() suite.NoMessageSent() } diff --git a/settings.go b/settings.go index f70bf9596..f457f9e2f 100644 --- a/settings.go +++ b/settings.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -16,7 +31,7 @@ type Settings struct { sessionSettings map[SessionID]*SessionSettings } -// Init initializes or resets a Settings instance +// Init initializes or resets a Settings instance. func (s *Settings) Init() { s.globalSettings = NewSessionSettings() s.sessionSettings = make(map[SessionID]*SessionSettings) @@ -28,7 +43,7 @@ func (s *Settings) lazyInit() { } } -// NewSettings creates a Settings instance +// NewSettings creates a Settings instance. func NewSettings() *Settings { s := &Settings{} s.Init() @@ -76,7 +91,7 @@ func sessionIDFromSessionSettings(globalSettings *SessionSettings, sessionSettin } // ParseSettings creates and initializes a Settings instance with config parsed from a Reader. -// Returns error if the config is has parse errors +// Returns error if the config is has parse errors. func ParseSettings(reader io.Reader) (*Settings, error) { s := NewSettings() @@ -149,7 +164,7 @@ func (s *Settings) SessionSettings() map[SessionID]*SessionSettings { return allSessionSettings } -// AddSession adds Session Settings to Settings instance. Returns an error if session settings with duplicate sessionID has already been added +// AddSession adds Session Settings to Settings instance. Returns an error if session settings with duplicate sessionID has already been added. func (s *Settings) AddSession(sessionSettings *SessionSettings) (SessionID, error) { s.lazyInit() diff --git a/settings_test.go b/settings_test.go index 9ce568e50..9ac8d9dcb 100644 --- a/settings_test.go +++ b/settings_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/sqlstore.go b/sqlstore.go index d0b1c5162..6ff8ac225 100644 --- a/sqlstore.go +++ b/sqlstore.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -45,12 +60,12 @@ func postgresPlaceholder(i int) string { return fmt.Sprintf("$%d", i+1) } -// NewSQLStoreFactory returns a sql-based implementation of MessageStoreFactory +// NewSQLStoreFactory returns a sql-based implementation of MessageStoreFactory. func NewSQLStoreFactory(settings *Settings) MessageStoreFactory { return sqlStoreFactory{settings: settings} } -// Create creates a new SQLStore implementation of the MessageStore interface +// Create creates a new SQLStore implementation of the MessageStore interface. func (f sqlStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { @@ -106,7 +121,7 @@ func newSQLStore(sessionID SessionID, driver string, dataSourceName string, conn return store, nil } -// Reset deletes the store records and sets the seqnums back to 1 +// Reset deletes the store records and sets the seqnums back to 1. func (store *sqlStore) Reset() error { s := store.sessionID _, err := store.db.Exec(sqlString(`DELETE FROM messages @@ -137,7 +152,7 @@ func (store *sqlStore) Reset() error { return err } -// Refresh reloads the store from the database +// Refresh reloads the store from the database. func (store *sqlStore) Refresh() error { if err := store.cache.Reset(); err != nil { return err @@ -194,17 +209,17 @@ func (store *sqlStore) populateCache() error { return err } -// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent +// NextSenderMsgSeqNum returns the next MsgSeqNum that will be sent. func (store *sqlStore) NextSenderMsgSeqNum() int { return store.cache.NextSenderMsgSeqNum() } -// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received +// NextTargetMsgSeqNum returns the next MsgSeqNum that should be received. func (store *sqlStore) NextTargetMsgSeqNum() int { return store.cache.NextTargetMsgSeqNum() } -// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent +// SetNextSenderMsgSeqNum sets the next MsgSeqNum that will be sent. func (store *sqlStore) SetNextSenderMsgSeqNum(next int) error { s := store.sessionID _, err := store.db.Exec(sqlString(`UPDATE sessions SET outgoing_seqnum = ? @@ -220,7 +235,7 @@ func (store *sqlStore) SetNextSenderMsgSeqNum(next int) error { return store.cache.SetNextSenderMsgSeqNum(next) } -// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received +// SetNextTargetMsgSeqNum sets the next MsgSeqNum that should be received. func (store *sqlStore) SetNextTargetMsgSeqNum(next int) error { s := store.sessionID _, err := store.db.Exec(sqlString(`UPDATE sessions SET incoming_seqnum = ? @@ -236,7 +251,7 @@ func (store *sqlStore) SetNextTargetMsgSeqNum(next int) error { return store.cache.SetNextTargetMsgSeqNum(next) } -// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent +// IncrNextSenderMsgSeqNum increments the next MsgSeqNum that will be sent. func (store *sqlStore) IncrNextSenderMsgSeqNum() error { if err := store.cache.IncrNextSenderMsgSeqNum(); err != nil { return errors.Wrap(err, "cache incr next") @@ -244,7 +259,7 @@ func (store *sqlStore) IncrNextSenderMsgSeqNum() error { return store.SetNextSenderMsgSeqNum(store.cache.NextSenderMsgSeqNum()) } -// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received +// IncrNextTargetMsgSeqNum increments the next MsgSeqNum that should be received. func (store *sqlStore) IncrNextTargetMsgSeqNum() error { if err := store.cache.IncrNextTargetMsgSeqNum(); err != nil { return errors.Wrap(err, "cache incr next") @@ -252,7 +267,7 @@ func (store *sqlStore) IncrNextTargetMsgSeqNum() error { return store.SetNextTargetMsgSeqNum(store.cache.NextTargetMsgSeqNum()) } -// CreationTime returns the creation time of the store +// CreationTime returns the creation time of the store. func (store *sqlStore) CreationTime() time.Time { return store.cache.CreationTime() } @@ -350,7 +365,7 @@ func (store *sqlStore) GetMessages(beginSeqNum, endSeqNum int) ([][]byte, error) return msgs, nil } -// Close closes the store's database connection +// Close closes the store's database connection. func (store *sqlStore) Close() error { if store.db != nil { store.db.Close() diff --git a/sqlstore_test.go b/sqlstore_test.go index da2c8a5a4..512c951fc 100644 --- a/sqlstore_test.go +++ b/sqlstore_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -16,7 +31,7 @@ import ( "github.com/stretchr/testify/suite" ) -// SqlStoreTestSuite runs all tests in the MessageStoreTestSuite against the SqlStore implementation +// SqlStoreTestSuite runs all tests in the MessageStoreTestSuite against the SqlStore implementation. type SQLStoreTestSuite struct { MessageStoreTestSuite sqlStoreRootPath string diff --git a/store.go b/store.go index 0ad5123fa..c56e1896e 100644 --- a/store.go +++ b/store.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -6,7 +21,7 @@ import ( "github.com/pkg/errors" ) -// The MessageStore interface provides methods to record and retrieve messages for resend purposes +// The MessageStore interface provides methods to record and retrieve messages for resend purposes. type MessageStore interface { NextSenderMsgSeqNum() int NextTargetMsgSeqNum() int @@ -29,7 +44,7 @@ type MessageStore interface { Close() error } -// The MessageStoreFactory interface is used by session to create a session specific message store +// The MessageStoreFactory interface is used by session to create a session specific message store. type MessageStoreFactory interface { Create(sessionID SessionID) (MessageStore, error) } @@ -80,12 +95,12 @@ func (store *memoryStore) Reset() error { } func (store *memoryStore) Refresh() error { - //nop, nothing to refresh + // NOP, nothing to refresh. return nil } func (store *memoryStore) Close() error { - //nop, nothing to close + // NOP, nothing to close. return nil } @@ -126,5 +141,5 @@ func (f memoryStoreFactory) Create(sessionID SessionID) (MessageStore, error) { return m, nil } -// NewMemoryStoreFactory returns a MessageStoreFactory instance that created in-memory MessageStores +// NewMemoryStoreFactory returns a MessageStoreFactory instance that created in-memory MessageStores. func NewMemoryStoreFactory() MessageStoreFactory { return memoryStoreFactory{} } diff --git a/store_test.go b/store_test.go index 7f0f8eafc..075b3fd6c 100644 --- a/store_test.go +++ b/store_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -9,13 +24,13 @@ import ( "github.com/stretchr/testify/suite" ) -// MessageStoreTestSuite is the suite of all tests that should be run against all MessageStore implementations +// MessageStoreTestSuite is the suite of all tests that should be run against all MessageStore implementations. type MessageStoreTestSuite struct { suite.Suite msgStore MessageStore } -// MemoryStoreTestSuite runs all tests in the MessageStoreTestSuite against the MemoryStore implementation +// MemoryStoreTestSuite runs all tests in the MessageStoreTestSuite against the MemoryStore implementation. type MemoryStoreTestSuite struct { MessageStoreTestSuite } diff --git a/tag.go b/tag.go index 475c7316a..01b28356f 100644 --- a/tag.go +++ b/tag.go @@ -1,6 +1,21 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix -// Tag is a typed int representing a FIX tag +// Tag is a typed int representing a FIX tag. type Tag int const ( @@ -61,7 +76,7 @@ const ( tagCheckSum Tag = 10 ) -// IsTrailer returns true if tag belongs in the message trailer +// IsTrailer returns true if tag belongs in the message trailer. func (t Tag) IsTrailer() bool { switch t { case tagSignatureLength, tagSignature, tagCheckSum: @@ -70,7 +85,7 @@ func (t Tag) IsTrailer() bool { return false } -// IsHeader returns true if tag belongs in the message header +// IsHeader returns true if tag belongs in the message header. func (t Tag) IsHeader() bool { switch t { case tagBeginString, diff --git a/tag_value.go b/tag_value.go index 75f532a85..6e721862f 100644 --- a/tag_value.go +++ b/tag_value.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -6,7 +21,7 @@ import ( "strconv" ) -// TagValue is a low-level FIX field abstraction +// TagValue is a low-level FIX field abstraction. type TagValue struct { tag Tag value []byte diff --git a/tag_value_test.go b/tag_value_test.go index 48883ed85..2c9ccc811 100644 --- a/tag_value_test.go +++ b/tag_value_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/tls.go b/tls.go index 62c7207f3..a86a49129 100644 --- a/tls.go +++ b/tls.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/tls_test.go b/tls_test.go index 9274b95dd..0bae6cd54 100644 --- a/tls_test.go +++ b/tls_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( diff --git a/validation.go b/validation.go index 14f6f9f0d..427fadacb 100644 --- a/validation.go +++ b/validation.go @@ -1,15 +1,30 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( "github.com/quickfixgo/quickfix/datadictionary" ) -// Validator validates a FIX message +// Validator validates a FIX message. type Validator interface { Validate(*Message) MessageRejectError } -// ValidatorSettings describe validation behavior +// ValidatorSettings describe validation behavior. type ValidatorSettings struct { CheckFieldsOutOfOrder bool RejectInvalidMessage bool @@ -33,7 +48,7 @@ type fixtValidator struct { settings ValidatorSettings } -// NewValidator creates a FIX message validator from the given data dictionaries +// NewValidator creates a FIX message validator from the given data dictionaries. func NewValidator(settings ValidatorSettings, appDataDictionary, transportDataDictionary *datadictionary.DataDictionary) Validator { if transportDataDictionary != nil { return &fixtValidator{ @@ -209,13 +224,13 @@ func validateVisitGroupField(fieldDef *datadictionary.FieldDef, fieldStack []Tag for len(fieldStack) > 0 { - //start of repeating group + // Start of repeating group. if int(fieldStack[0].tag) == fieldDef.Fields[0].Tag() { childDefs = fieldDef.Fields groupCount++ } - //group complete + // Group complete. if len(childDefs) == 0 { break } diff --git a/validation_test.go b/validation_test.go index 25a47802a..da0e65f2b 100644 --- a/validation_test.go +++ b/validation_test.go @@ -1,3 +1,18 @@ +// Copyright (c) quickfixengine.org All rights reserved. +// +// This file may be distributed under the terms of the quickfixengine.org +// license as defined by quickfixengine.org and appearing in the file +// LICENSE included in the packaging of this file. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING +// THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE. +// +// See http://www.quickfixengine.org/LICENSE for licensing information. +// +// Contact ask@quickfixengine.org if any conditions of this licensing +// are not clear to you. + package quickfix import ( @@ -66,13 +81,13 @@ func TestValidate(t *testing.T) { switch { case reject.RefTagID() == nil && test.ExpectedRefTagID == nil: - //ok, expected and actual ref tag not set + // OK, expected and actual ref tag not set. case reject.RefTagID() != nil && test.ExpectedRefTagID == nil: t.Errorf("%v: Unexpected RefTag '%v'", test.TestName, *reject.RefTagID()) case reject.RefTagID() == nil && test.ExpectedRefTagID != nil: t.Errorf("%v: Expected RefTag '%v'", test.TestName, *test.ExpectedRefTagID) case *reject.RefTagID() == *test.ExpectedRefTagID: - //ok, tags equal + // OK, tags equal. default: t.Errorf("%v: Expected RefTag '%v' got '%v'", test.TestName, *test.ExpectedRefTagID, *reject.RefTagID()) } @@ -193,7 +208,7 @@ func tcTagNotDefinedForMessage() validateTest { } func tcTagIsDefinedForMessage() validateTest { - //compare to tcTagIsNotDefinedForMessage + // Compare to `tcTagIsNotDefinedForMessage`. dict, _ := datadictionary.Parse("spec/FIX43.xml") validator := NewValidator(defaultValidatorSettings, dict, nil) validMsg := createFIX43NewOrderSingle() @@ -227,9 +242,7 @@ func tcFieldNotFoundBody() validateTest { SetField(Tag(38), FIXString("A")) tag := Tag(40) - //ord type is required - //invalidMsg1.Body.SetField(Tag(40), "A")) - + // Ord type is required. invalidMsg1.Body.SetField(Tag(40), "A")). msgBytes := invalidMsg1.build() return validateTest{ @@ -259,9 +272,8 @@ func tcFieldNotFoundHeader() validateTest { SetField(tagSenderCompID, FIXString("0")). SetField(tagTargetCompID, FIXString("0")). SetField(tagMsgSeqNum, FIXString("0")) - //sending time is required - //invalidMsg2.Header.FieldMap.SetField(tag.SendingTime, "0")) + // Sending time is required. invalidMsg2.Header.FieldMap.SetField(tag.SendingTime, "0")). tag := tagSendingTime msgBytes := invalidMsg2.build() @@ -348,7 +360,7 @@ func tcTagSpecifiedOutOfRequiredOrderHeader() validateTest { builder := createFIX40NewOrderSingle() tag := tagOnBehalfOfCompID - //should be in header + // Should be in header. builder.Body.SetField(tag, FIXString("CWB")) msgBytes := builder.build() @@ -367,7 +379,7 @@ func tcTagSpecifiedOutOfRequiredOrderTrailer() validateTest { builder := createFIX40NewOrderSingle() tag := tagSignature - //should be in trailer + // Should be in trailer. builder.Body.SetField(tag, FIXString("SIG")) msgBytes := builder.build() @@ -428,7 +440,7 @@ func tcTagSpecifiedOutOfRequiredOrderDisabledHeader() validateTest { builder := createFIX40NewOrderSingle() tag := tagOnBehalfOfCompID - //should be in header + // Should be in header. builder.Body.SetField(tag, FIXString("CWB")) msgBytes := builder.build() @@ -448,7 +460,7 @@ func tcTagSpecifiedOutOfRequiredOrderDisabledTrailer() validateTest { builder := createFIX40NewOrderSingle() tag := tagSignature - //should be in trailer + // Should be in trailer. builder.Body.SetField(tag, FIXString("SIG")) msgBytes := builder.build() @@ -524,27 +536,27 @@ func TestValidateVisitField(t *testing.T) { expectReject bool expectedRejectReason int }{ - //non-repeating + // Non-repeating. {expectedRemFields: 0, fieldDef: fieldDef0, fields: []TagValue{field}}, - //single field group + // Single field group. {expectedRemFields: 0, fieldDef: groupFieldDef, fields: []TagValue{groupID, repField1}}, - //multiple field group + // Multiple field group. {expectedRemFields: 0, fieldDef: groupFieldDef, fields: []TagValue{groupID, repField1, repField2}}, - //test with trailing tag not in group + // Test with trailing tag not in group. {expectedRemFields: 1, fieldDef: groupFieldDef, fields: []TagValue{groupID, repField1, repField2, field}}, - //repeats + // Repeats. {expectedRemFields: 1, fieldDef: groupFieldDef, fields: []TagValue{groupID2, repField1, repField2, repField1, repField2, field}}, - //REJECT: group size declared > actual group size + // REJECT: group size declared > actual group size. {expectReject: true, fieldDef: groupFieldDef, fields: []TagValue{groupID3, repField1, repField2, repField1, repField2, field}, @@ -555,7 +567,7 @@ func TestValidateVisitField(t *testing.T) { fields: []TagValue{groupID3, repField1, repField1, field}, expectedRejectReason: rejectReasonIncorrectNumInGroupCountForRepeatingGroup, }, - //REJECT: group size declared < actual group size + // REJECT: group size declared < actual group size. {expectReject: true, fieldDef: groupFieldDef, fields: []TagValue{groupID, repField1, repField2, repField1, repField2, field}, From 0f9a0059d461351fc45fce55e13bb0c52b332e00 Mon Sep 17 00:00:00 2001 From: Andrey Kuznetsov Date: Wed, 7 Mar 2018 23:25:37 +0300 Subject: [PATCH 016/178] set targetSubID to session --- registry.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/registry.go b/registry.go index 180bc8035..747578a19 100644 --- a/registry.go +++ b/registry.go @@ -49,7 +49,10 @@ func Send(m Messagable) (err error) { return nil } - sessionID := SessionID{BeginString: string(beginString), TargetCompID: string(targetCompID), SenderCompID: string(senderCompID)} + var targetSubID FIXString + msg.Header.GetField(tagTargetSubID, &targetSubID) + + sessionID := SessionID{BeginString: string(beginString), TargetCompID: string(targetCompID), SenderCompID: string(senderCompID), TargetSubID: string(targetSubID)} return SendToTarget(msg, sessionID) } From 831392f017a0930837732c95d6468280410bb7b8 Mon Sep 17 00:00:00 2001 From: Matt Rasband <2184696+mattrasband@users.noreply.github.com> Date: Fri, 3 Jun 2022 08:43:38 -0600 Subject: [PATCH 017/178] Allow stores to fall back to global settings for dynamic sessions * Dynamic sessions are not added to the settings until after the session factory has created the sessions. In this scenario the filestore and sqlstore are unable to get the settings and fail to create the various message stores. Often these settings are set globally so we should try falling back before failing to create the message store. --- filestore.go | 10 +++++++++- sqlstore.go | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/filestore.go b/filestore.go index 2a548cadb..e0766fd08 100644 --- a/filestore.go +++ b/filestore.go @@ -61,10 +61,18 @@ func NewFileStoreFactory(settings *Settings) MessageStoreFactory { // Create creates a new FileStore implementation of the MessageStore interface. func (f fileStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { + globalSettings := f.settings.GlobalSettings() + dynamicSessions, _ := globalSettings.BoolSetting(config.DynamicSessions) + sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { - return nil, fmt.Errorf("unknown session: %v", sessionID) + if dynamicSessions { + sessionSettings = globalSettings + } else { + return nil, fmt.Errorf("unknown session: %v", sessionID) + } } + dirname, err := sessionSettings.Setting(config.FileStorePath) if err != nil { return nil, err diff --git a/sqlstore.go b/sqlstore.go index 6ff8ac225..5e492be2c 100644 --- a/sqlstore.go +++ b/sqlstore.go @@ -67,10 +67,18 @@ func NewSQLStoreFactory(settings *Settings) MessageStoreFactory { // Create creates a new SQLStore implementation of the MessageStore interface. func (f sqlStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { + globalSettings := f.settings.GlobalSettings() + dynamicSessions, _ := globalSettings.BoolSetting(config.DynamicSessions) + sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { - return nil, fmt.Errorf("unknown session: %v", sessionID) + if dynamicSessions { + sessionSettings = globalSettings + } else { + return nil, fmt.Errorf("unknown session: %v", sessionID) + } } + sqlDriver, err := sessionSettings.Setting(config.SQLStoreDriver) if err != nil { return nil, err From 0dd076e88623a3a1b4a54266ada1412f3815437c Mon Sep 17 00:00:00 2001 From: Matt Rasband <2184696+mattrasband@users.noreply.github.com> Date: Fri, 3 Jun 2022 08:50:21 -0600 Subject: [PATCH 018/178] Include mongostore in fixes to #484 --- mongostore.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mongostore.go b/mongostore.go index c9bc37ac2..290cdc236 100644 --- a/mongostore.go +++ b/mongostore.go @@ -61,9 +61,16 @@ func NewMongoStoreFactoryPrefixed(settings *Settings, collectionsPrefix string) // Create creates a new MongoStore implementation of the MessageStore interface. func (f mongoStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, err error) { + globalSettings := f.settings.GlobalSettings() + dynamicSessions, _ := globalSettings.BoolSetting(config.DynamicSessions) + sessionSettings, ok := f.settings.SessionSettings()[sessionID] if !ok { - return nil, fmt.Errorf("unknown session: %v", sessionID) + if dynamicSessions { + sessionSettings = globalSettings + } else { + return nil, fmt.Errorf("unknown session: %v", sessionID) + } } mongoConnectionURL, err := sessionSettings.Setting(config.MongoStoreConnection) if err != nil { From 111c2093bac07c0f13e63647005ac515f4d847ba Mon Sep 17 00:00:00 2001 From: Michael Ackley Date: Mon, 30 Jan 2023 22:18:02 -0600 Subject: [PATCH 019/178] Clean-up unused --- message.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/message.go b/message.go index efe964395..6fd769186 100644 --- a/message.go +++ b/message.go @@ -205,7 +205,6 @@ func ParseMessageWithDataDictionary( return } - //prevTag := tagMsgType xmlDataLen := 0 xmlDataMsg := false @@ -245,7 +244,6 @@ func ParseMessageWithDataDictionary( msg.bodyBytes = rawBytes } - //prevTag = parsedFieldBytes.tag if parsedFieldBytes.tag == tagXMLDataLen { xmlDataLen, _ = msg.Header.GetInt(tagXMLDataLen) } From a18c8897b5004dc50e54a86329126e9f34b2f717 Mon Sep 17 00:00:00 2001 From: Michael Ackley Date: Mon, 30 Jan 2023 23:56:51 -0600 Subject: [PATCH 020/178] Revert and fix send message session registry --- fix_string_test.go | 2 ++ registry.go | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/fix_string_test.go b/fix_string_test.go index c17a69d3c..4f3712333 100644 --- a/fix_string_test.go +++ b/fix_string_test.go @@ -44,6 +44,8 @@ func TestFIXStringRead(t *testing.T) { expectError bool }{ {[]byte("blah"), "blah", false}, + {nil, "", false}, + {[]byte(""), "", false}, } for _, test := range tests { diff --git a/registry.go b/registry.go index 747578a19..291d44bee 100644 --- a/registry.go +++ b/registry.go @@ -45,14 +45,10 @@ func Send(m Messagable) (err error) { var senderCompID FIXString if err := msg.Header.GetField(tagSenderCompID, &senderCompID); err != nil { - - return nil + return err } - var targetSubID FIXString - msg.Header.GetField(tagTargetSubID, &targetSubID) - - sessionID := SessionID{BeginString: string(beginString), TargetCompID: string(targetCompID), SenderCompID: string(senderCompID), TargetSubID: string(targetSubID)} + sessionID := SessionID{BeginString: string(beginString), TargetCompID: string(targetCompID), SenderCompID: string(senderCompID)} return SendToTarget(msg, sessionID) } From 1f4e57093df54e957b5c92a8413d11522d6e64a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 01:36:37 +0000 Subject: [PATCH 021/178] Bump github.com/stretchr/testify from 1.8.1 to 1.8.2 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.1 to 1.8.2. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.1...v1.8.2) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 10cbdb8b1..30a566aaa 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.16 github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 - github.com/stretchr/testify v1.8.1 + github.com/stretchr/testify v1.8.2 go.mongodb.org/mongo-driver v1.11.1 golang.org/x/net v0.5.0 ) diff --git a/go.sum b/go.sum index 376aa7687..bfabda208 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= From 06a24e1e2ce6cd13be0db1d02daa86b2d11dc239 Mon Sep 17 00:00:00 2001 From: Sai G Date: Tue, 28 Feb 2023 17:10:49 -0500 Subject: [PATCH 022/178] Remove tag from field map --- field_map.go | 8 ++++++++ field_map_test.go | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/field_map.go b/field_map.go index e940790f5..17903ed17 100644 --- a/field_map.go +++ b/field_map.go @@ -227,6 +227,14 @@ func (m *FieldMap) SetString(tag Tag, value string) *FieldMap { return m.SetBytes(tag, []byte(value)) } +// Remove removes a tag from field map +func (m *FieldMap) Remove(tag Tag) { + m.rwLock.Lock() + defer m.rwLock.Unlock() + + delete(m.tagLookup, tag) +} + // Clear purges all fields from field map. func (m *FieldMap) Clear() { m.rwLock.Lock() diff --git a/field_map_test.go b/field_map_test.go index 5d7da7041..0e9078734 100644 --- a/field_map_test.go +++ b/field_map_test.go @@ -190,3 +190,15 @@ func TestFieldMap_CopyInto(t *testing.T) { assert.Nil(t, err) assert.Equal(t, "a", s) } + +func TestFieldMap_Remove(t *testing.T) { + var fMap FieldMap + fMap.init() + + fMap.SetField(1, FIXString("hello")) + fMap.SetField(2, FIXString("world")) + + fMap.Remove(1) + assert.False(t, fMap.Has(1)) + assert.True(t, fMap.Has(2)) +} From d1ac11dfcef04c2630353abf20800b147c62e0e5 Mon Sep 17 00:00:00 2001 From: Sai G Date: Tue, 28 Feb 2023 17:24:18 -0500 Subject: [PATCH 023/178] fix linter failure --- field_map.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/field_map.go b/field_map.go index 17903ed17..18216f81c 100644 --- a/field_map.go +++ b/field_map.go @@ -227,7 +227,7 @@ func (m *FieldMap) SetString(tag Tag, value string) *FieldMap { return m.SetBytes(tag, []byte(value)) } -// Remove removes a tag from field map +// Remove removes a tag from field map. func (m *FieldMap) Remove(tag Tag) { m.rwLock.Lock() defer m.rwLock.Unlock() From 65ca3790cc5ce48ebdff2fae2b33d9689dd627cf Mon Sep 17 00:00:00 2001 From: Neal Patel Date: Mon, 6 Mar 2023 13:33:36 -0800 Subject: [PATCH 024/178] Add message.Bytes() to avoid string conversion --- message.go | 9 ++++++++- message_test.go | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/message.go b/message.go index 6fd769186..63dca9043 100644 --- a/message.go +++ b/message.go @@ -272,7 +272,6 @@ func ParseMessageWithDataDictionary( } return - } func isHeaderField(tag Tag, dataDict *datadictionary.DataDictionary) bool { @@ -390,6 +389,14 @@ func extractField(parsedFieldBytes *TagValue, buffer []byte) (remBytes []byte, e return buffer[(endIndex + 1):], err } +func (m *Message) Bytes() []byte { + if m.rawMessage != nil { + return m.rawMessage.Bytes() + } + + return m.build() +} + func (m *Message) String() string { if m.rawMessage != nil { return m.rawMessage.String() diff --git a/message_test.go b/message_test.go index 7c5557b9b..9bb223751 100644 --- a/message_test.go +++ b/message_test.go @@ -222,12 +222,14 @@ func (s *MessageSuite) TestCopyIntoMessage() { s.Nil(ParseMessage(s.msg, bytes.NewBufferString(newMsgString))) s.True(s.msg.IsMsgTypeOf("A")) s.Equal(s.msg.String(), newMsgString) + s.Equal(string(s.msg.Bytes()), newMsgString) // clear the source buffer also msgBuf.Reset() s.True(dest.IsMsgTypeOf("D")) s.Equal(dest.String(), renderedString) + s.Equal(string(dest.Bytes()), renderedString) } func checkFieldInt(s *MessageSuite, fields FieldMap, tag, expected int) { From 0e376c451883c23ae1e0e82cab11331adaf09e45 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Apr 2023 00:57:53 +0000 Subject: [PATCH 025/178] Bump golang.org/x/net from 0.5.0 to 0.9.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.5.0 to 0.9.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/compare/v0.5.0...v0.9.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 10cbdb8b1..ba85909c4 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.1 go.mongodb.org/mongo-driver v1.11.1 - golang.org/x/net v0.5.0 + golang.org/x/net v0.9.0 ) require ( @@ -27,7 +27,7 @@ require ( github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect golang.org/x/crypto v0.3.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/text v0.6.0 // indirect + golang.org/x/text v0.9.0 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 376aa7687..d821ac2b7 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= -golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -73,8 +73,8 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From b6691d8fed1f6285fa5319b3691bc0e44baadf0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 May 2023 00:58:03 +0000 Subject: [PATCH 026/178] Bump go.mongodb.org/mongo-driver from 1.11.1 to 1.11.6 Bumps [go.mongodb.org/mongo-driver](https://github.com/mongodb/mongo-go-driver) from 1.11.1 to 1.11.6. - [Release notes](https://github.com/mongodb/mongo-go-driver/releases) - [Commits](https://github.com/mongodb/mongo-go-driver/compare/v1.11.1...v1.11.6) --- updated-dependencies: - dependency-name: go.mongodb.org/mongo-driver dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 10cbdb8b1..d3b7bcff2 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.1 - go.mongodb.org/mongo-driver v1.11.1 + go.mongodb.org/mongo-driver v1.11.6 golang.org/x/net v0.5.0 ) diff --git a/go.sum b/go.sum index 376aa7687..df339f816 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgk github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk= github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4= -go.mongodb.org/mongo-driver v1.11.1 h1:QP0znIRTuL0jf1oBQoAoM0C6ZJfBK4kx0Uumtv1A7w8= -go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= +go.mongodb.org/mongo-driver v1.11.6 h1:XM7G6PjiGAO5betLF13BIa5TlLUUE3uJ/2Ox3Lz1K+o= +go.mongodb.org/mongo-driver v1.11.6/go.mod h1:G9TgswdsWjX4tmDA5zfs2+6AEPpYJwqblyjsfuh8oXY= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= From a02cb5144189b138eca02a5a578708ab1c60272f Mon Sep 17 00:00:00 2001 From: Adam Krieg Date: Tue, 2 Nov 2021 16:50:10 -0400 Subject: [PATCH 027/178] Add support for QuickfixJ option FileStoreSync which controls whether we wait until the write hits the filesystem for each write --- config/configuration.go | 1 + filestore.go | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/config/configuration.go b/config/configuration.go index 431be8ea7..1d70f75c7 100644 --- a/config/configuration.go +++ b/config/configuration.go @@ -50,6 +50,7 @@ const ( HeartBtIntOverride string = "HeartBtIntOverride" FileLogPath string = "FileLogPath" FileStorePath string = "FileStorePath" + FileStoreSync string = "FileStoreSync" SQLStoreDriver string = "SQLStoreDriver" SQLStoreDataSourceName string = "SQLStoreDataSourceName" SQLStoreConnMaxLifetime string = "SQLStoreConnMaxLifetime" diff --git a/filestore.go b/filestore.go index e0766fd08..120ba83c0 100644 --- a/filestore.go +++ b/filestore.go @@ -52,6 +52,7 @@ type fileStore struct { sessionFile *os.File senderSeqNumsFile *os.File targetSeqNumsFile *os.File + fileSync bool } // NewFileStoreFactory returns a file-based implementation of MessageStoreFactory. @@ -77,10 +78,19 @@ func (f fileStoreFactory) Create(sessionID SessionID) (msgStore MessageStore, er if err != nil { return nil, err } - return newFileStore(sessionID, dirname) + var fsync bool + if sessionSettings.HasSetting(config.FileStoreSync) { + fsync, err = sessionSettings.BoolSetting(config.FileStoreSync) + if err != nil { + return nil, err + } + } else { + fsync = true //existing behavior is to fsync writes + } + return newFileStore(sessionID, dirname, fsync) } -func newFileStore(sessionID SessionID, dirname string) (*fileStore, error) { +func newFileStore(sessionID SessionID, dirname string, fileSync bool) (*fileStore, error) { if err := os.MkdirAll(dirname, os.ModePerm); err != nil { return nil, err } @@ -96,6 +106,7 @@ func newFileStore(sessionID SessionID, dirname string) (*fileStore, error) { sessionFname: path.Join(dirname, fmt.Sprintf("%s.%s", sessionPrefix, "session")), senderSeqNumsFname: path.Join(dirname, fmt.Sprintf("%s.%s", sessionPrefix, "senderseqnums")), targetSeqNumsFname: path.Join(dirname, fmt.Sprintf("%s.%s", sessionPrefix, "targetseqnums")), + fileSync: fileSync, } if err := store.Refresh(); err != nil { @@ -232,8 +243,10 @@ func (store *fileStore) setSession() error { if _, err := store.sessionFile.Write(data); err != nil { return fmt.Errorf("unable to write to file: %s: %s", store.sessionFname, err.Error()) } - if err := store.sessionFile.Sync(); err != nil { - return fmt.Errorf("unable to flush file: %s: %s", store.sessionFname, err.Error()) + if store.fileSync { + if err := store.sessionFile.Sync(); err != nil { + return fmt.Errorf("unable to flush file: %s: %s", store.sessionFname, err.Error()) + } } return nil } @@ -245,8 +258,10 @@ func (store *fileStore) setSeqNum(f *os.File, seqNum int) error { if _, err := fmt.Fprintf(f, "%019d", seqNum); err != nil { return fmt.Errorf("unable to write to file: %s: %s", f.Name(), err.Error()) } - if err := f.Sync(); err != nil { - return fmt.Errorf("unable to flush file: %s: %s", f.Name(), err.Error()) + if store.fileSync { + if err := f.Sync(); err != nil { + return fmt.Errorf("unable to flush file: %s: %s", f.Name(), err.Error()) + } } return nil } @@ -313,11 +328,13 @@ func (store *fileStore) SaveMessage(seqNum int, msg []byte) error { if _, err := store.bodyFile.Write(msg); err != nil { return fmt.Errorf("unable to write to file: %s: %s", store.bodyFname, err.Error()) } - if err := store.bodyFile.Sync(); err != nil { - return fmt.Errorf("unable to flush file: %s: %s", store.bodyFname, err.Error()) - } - if err := store.headerFile.Sync(); err != nil { - return fmt.Errorf("unable to flush file: %s: %s", store.headerFname, err.Error()) + if store.fileSync { + if err := store.bodyFile.Sync(); err != nil { + return fmt.Errorf("unable to flush file: %s: %s", store.bodyFname, err.Error()) + } + if err := store.headerFile.Sync(); err != nil { + return fmt.Errorf("unable to flush file: %s: %s", store.headerFname, err.Error()) + } } store.offsets[seqNum] = msgDef{offset: offset, size: len(msg)} From a353cb0fc9b9743b86199888194d407b687f30ef Mon Sep 17 00:00:00 2001 From: Adam Krieg Date: Tue, 31 Aug 2021 16:49:24 -0400 Subject: [PATCH 028/178] Prevent staleness check from happening during replay, which can necesssarily involve receiving old messages --- resend_state_test.go | 30 ++++++++++++++++++++++++++++++ session.go | 10 +++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/resend_state_test.go b/resend_state_test.go index 093660d85..88a2ee8de 100644 --- a/resend_state_test.go +++ b/resend_state_test.go @@ -17,6 +17,7 @@ package quickfix import ( "testing" + "time" "github.com/stretchr/testify/suite" @@ -189,3 +190,32 @@ func (s *resendStateTestSuite) TestFixMsgInResendChunk() { s.FieldEquals(tagBeginSeqNo, 3, s.MockApp.lastToAdmin.Body) s.FieldEquals(tagEndSeqNo, 0, s.MockApp.lastToAdmin.Body) } + +//TestFixMsgResendWithOldSendingTime Tests that we suspend staleness checks during replay +//as a replayed message may be arbitrarily old +func (s *resendStateTestSuite) TestFixMsgResendWithOldSendingTime() { + s.session.State = inSession{} + s.ResendRequestChunkSize = 2 + + //in session expects seq number 1, send too high + s.MessageFactory.SetNextSeqNum(4) + s.MockApp.On("ToAdmin") + + msgSeqNum4 := s.NewOrderSingle() + s.fixMsgIn(s.session, msgSeqNum4) + + s.MockApp.AssertExpectations(s.T()) + s.State(resendState{}) + s.LastToAdminMessageSent() + s.MessageType(string(msgTypeResendRequest), s.MockApp.lastToAdmin) + s.FieldEquals(tagBeginSeqNo, 1, s.MockApp.lastToAdmin.Body) + s.FieldEquals(tagEndSeqNo, 2, s.MockApp.lastToAdmin.Body) + s.NextTargetMsgSeqNum(1) + + msgSeqNum5 := s.NewOrderSingle() + //set the sending time far enough in the past to trip the staleness check + msgSeqNum5.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: time.Now().Add(-s.MaxLatency)}) + s.fixMsgIn(s.session, msgSeqNum5) + s.State(resendState{}) + s.NextTargetMsgSeqNum(1) +} diff --git a/session.go b/session.go index e3a89b07c..ab53935e5 100644 --- a/session.go +++ b/session.go @@ -516,10 +516,14 @@ func (s *session) verifySelect(msg *Message, checkTooHigh bool, checkTooLow bool return reject } - if reject := s.checkSendingTime(msg); reject != nil { - return reject + switch s.stateMachine.State.(type) { + case resendState: + //Don't check staleness of a replay + default: + if reject := s.checkSendingTime(msg); reject != nil { + return reject + } } - if checkTooLow { if reject := s.checkTargetTooLow(msg); reject != nil { return reject From 6dbde4ab7d80d12e14ec1a8b243334bd894aaf36 Mon Sep 17 00:00:00 2001 From: Michael Ackley Date: Sun, 7 May 2023 22:00:40 -0500 Subject: [PATCH 029/178] Update resend_state_test.go --- resend_state_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/resend_state_test.go b/resend_state_test.go index 88a2ee8de..d6bd0eb50 100644 --- a/resend_state_test.go +++ b/resend_state_test.go @@ -191,13 +191,13 @@ func (s *resendStateTestSuite) TestFixMsgInResendChunk() { s.FieldEquals(tagEndSeqNo, 0, s.MockApp.lastToAdmin.Body) } -//TestFixMsgResendWithOldSendingTime Tests that we suspend staleness checks during replay -//as a replayed message may be arbitrarily old +// TestFixMsgResendWithOldSendingTime tests that we suspend staleness checks during replay +// as a replayed message may be arbitrarily old. func (s *resendStateTestSuite) TestFixMsgResendWithOldSendingTime() { s.session.State = inSession{} s.ResendRequestChunkSize = 2 - //in session expects seq number 1, send too high + // In session expects seq number 1, send too high. s.MessageFactory.SetNextSeqNum(4) s.MockApp.On("ToAdmin") @@ -213,7 +213,7 @@ func (s *resendStateTestSuite) TestFixMsgResendWithOldSendingTime() { s.NextTargetMsgSeqNum(1) msgSeqNum5 := s.NewOrderSingle() - //set the sending time far enough in the past to trip the staleness check + // Set the sending time far enough in the past to trip the staleness check. msgSeqNum5.Header.SetField(tagSendingTime, FIXUTCTimestamp{Time: time.Now().Add(-s.MaxLatency)}) s.fixMsgIn(s.session, msgSeqNum5) s.State(resendState{}) From 3ce9479197a8f43fa301fbe43dc3864d4b761d43 Mon Sep 17 00:00:00 2001 From: Tiger Lee Date: Thu, 17 Sep 2020 17:47:46 +0800 Subject: [PATCH 030/178] Avoid to block thread while write to a nil channel if session disconnected during sendBytes, session.messageOut may be set to nil before write in session.onDisconnect() --- session.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/session.go b/session.go index ab53935e5..b359245e2 100644 --- a/session.go +++ b/session.go @@ -367,6 +367,11 @@ func (s *session) EnqueueBytesAndSend(msg []byte) { } func (s *session) sendBytes(msg []byte) { + if s.messageOut == nil { + s.log.OnEventf("Failed to send: disconnected") + return + } + s.log.OnOutgoing(msg) s.messageOut <- msg s.stateTimer.Reset(s.HeartBtInt) From 488335669d5ef8022b741f79903d414823b58aae Mon Sep 17 00:00:00 2001 From: Adam Krieg Date: Thu, 30 Sep 2021 16:03:21 -0400 Subject: [PATCH 031/178] Trim extra non-ascii characters that can arise from manually editing sequence number files --- filestore.go | 5 +++-- filestore_test.go | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/filestore.go b/filestore.go index 120ba83c0..650bd388a 100644 --- a/filestore.go +++ b/filestore.go @@ -22,6 +22,7 @@ import ( "os" "path" "strconv" + "strings" "time" "github.com/pkg/errors" @@ -213,7 +214,7 @@ func (store *fileStore) populateCache() (creationTimePopulated bool, err error) } if senderSeqNumBytes, err := ioutil.ReadFile(store.senderSeqNumsFname); err == nil { - if senderSeqNum, err := strconv.Atoi(string(senderSeqNumBytes)); err == nil { + if senderSeqNum, err := strconv.Atoi(strings.Trim(string(senderSeqNumBytes), "\r\n")); err == nil { if err = store.cache.SetNextSenderMsgSeqNum(senderSeqNum); err != nil { return creationTimePopulated, errors.Wrap(err, "cache set next sender") } @@ -221,7 +222,7 @@ func (store *fileStore) populateCache() (creationTimePopulated bool, err error) } if targetSeqNumBytes, err := ioutil.ReadFile(store.targetSeqNumsFname); err == nil { - if targetSeqNum, err := strconv.Atoi(string(targetSeqNumBytes)); err == nil { + if targetSeqNum, err := strconv.Atoi(strings.Trim(string(targetSeqNumBytes),"\r\n")); err == nil { if err = store.cache.SetNextTargetMsgSeqNum(targetSeqNum); err != nil { return creationTimePopulated, errors.Wrap(err, "cache set next target") } diff --git a/filestore_test.go b/filestore_test.go index 3713ac8a9..efb6a9283 100644 --- a/filestore_test.go +++ b/filestore_test.go @@ -19,10 +19,12 @@ import ( "fmt" "os" "path" + "strconv" "strings" "testing" "time" + assert2 "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" ) @@ -62,3 +64,14 @@ func (suite *FileStoreTestSuite) TearDownTest() { func TestFileStoreTestSuite(t *testing.T) { suite.Run(t, new(FileStoreTestSuite)) } + +func TestStringParse(t *testing.T) { + assert := assert2.New(t) + i, err := strconv.Atoi(strings.Trim("00005\n", "\r\n")) + assert.Nil(err) + assert.Equal(5, i) + + i, err = strconv.Atoi(strings.Trim("00006\r", "\r\n")) + assert.Nil(err) + assert.Equal(6, i) +} From 982d831d7e099e3e7f23b9d5bef87558f420787f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 May 2023 00:57:43 +0000 Subject: [PATCH 032/178] Bump golang.org/x/net from 0.9.0 to 0.10.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.9.0 to 0.10.0. - [Commits](https://github.com/golang/net/compare/v0.9.0...v0.10.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index b79d1f433..abfef601e 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.2 go.mongodb.org/mongo-driver v1.11.6 - golang.org/x/net v0.9.0 + golang.org/x/net v0.10.0 ) require ( diff --git a/go.sum b/go.sum index e7408ef38..42a8a9100 100644 --- a/go.sum +++ b/go.sum @@ -59,8 +59,8 @@ golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From f275c045b8e1c79413c753644ac393de8717c88b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 31 May 2023 00:57:49 +0000 Subject: [PATCH 033/178] Bump github.com/stretchr/testify from 1.8.2 to 1.8.4 Bumps [github.com/stretchr/testify](https://github.com/stretchr/testify) from 1.8.2 to 1.8.4. - [Release notes](https://github.com/stretchr/testify/releases) - [Commits](https://github.com/stretchr/testify/compare/v1.8.2...v1.8.4) --- updated-dependencies: - dependency-name: github.com/stretchr/testify dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index abfef601e..d26261e24 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/mattn/go-sqlite3 v1.14.16 github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.8.4 go.mongodb.org/mongo-driver v1.11.6 golang.org/x/net v0.10.0 ) diff --git a/go.sum b/go.sum index 42a8a9100..3576f3a2a 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,8 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= From 679ec50a70f0124c89c30ac3d8d5ee30f661f2dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 00:59:18 +0000 Subject: [PATCH 034/178] Bump github.com/mattn/go-sqlite3 from 1.14.16 to 1.14.17 Bumps [github.com/mattn/go-sqlite3](https://github.com/mattn/go-sqlite3) from 1.14.16 to 1.14.17. - [Release notes](https://github.com/mattn/go-sqlite3/releases) - [Commits](https://github.com/mattn/go-sqlite3/compare/v1.14.16...v1.14.17) --- updated-dependencies: - dependency-name: github.com/mattn/go-sqlite3 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index abfef601e..4cf256c31 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/armon/go-proxyproto v0.0.0-20210323213023-7e956b284f0a - github.com/mattn/go-sqlite3 v1.14.16 + github.com/mattn/go-sqlite3 v1.14.17 github.com/pkg/errors v0.9.1 github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.8.2 diff --git a/go.sum b/go.sum index 42a8a9100..c30c84da2 100644 --- a/go.sum +++ b/go.sum @@ -19,8 +19,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= -github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= From 60dde0588fa69688b56c594f5cd5bd3bed77fde5 Mon Sep 17 00:00:00 2001 From: Alexandre Thibault Date: Tue, 1 Aug 2023 14:15:48 +0200 Subject: [PATCH 035/178] Check RejectInvalidMessage on FIXT validation Signed-off-by: Alexandre Thibault --- .../14i_RepeatingGroupCountNotEqual.def | 4 +- .../14i_RepeatingGroupCountNotEqual.def | 4 +- validation.go | 12 +- validation_test.go | 424 ++++++++++++++++++ 4 files changed, 435 insertions(+), 9 deletions(-) diff --git a/_test/definitions/server/fix50sp1/14i_RepeatingGroupCountNotEqual.def b/_test/definitions/server/fix50sp1/14i_RepeatingGroupCountNotEqual.def index e223b0410..5fce36436 100644 --- a/_test/definitions/server/fix50sp1/14i_RepeatingGroupCountNotEqual.def +++ b/_test/definitions/server/fix50sp1/14i_RepeatingGroupCountNotEqual.def @@ -11,7 +11,7 @@ E8=FIXT.1.19=6735=A34=149=ISLD52=00000000-00:00:00.00056=TW98=0108=2113 #------------------------ #New order message with incorrect repeating group "count". NoTradingSessions (386) -I8=FIXT.1.135=D34=249=TW52=