From 613d40d371812d8af1cef4ea3937fbdf3393539e Mon Sep 17 00:00:00 2001 From: Grant Birchmeier Date: Thu, 1 Feb 2024 09:51:49 -0600 Subject: [PATCH] cleanup/nullable-ize HttpServer/Session/Settings --- QuickFIXn/HttpServer.cs | 15 ++- QuickFIXn/SessionID.cs | 131 ++++++-------------- QuickFIXn/SessionSchedule.cs | 194 ++++++++++++------------------ QuickFIXn/SessionSettings.cs | 103 ++++++++-------- QuickFIXn/Settings.cs | 20 +-- RELEASE_NOTES.md | 4 + UnitTests/SessionScheduleTests.cs | 95 --------------- 7 files changed, 193 insertions(+), 369 deletions(-) diff --git a/QuickFIXn/HttpServer.cs b/QuickFIXn/HttpServer.cs index 2de690779..d0c452e3a 100644 --- a/QuickFIXn/HttpServer.cs +++ b/QuickFIXn/HttpServer.cs @@ -153,7 +153,10 @@ private string EnableSessions(HttpListenerRequest request, StringBuilder pageBui private string RefreshSession(HttpListenerRequest request, StringBuilder pageBuilder) { - SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]); + SessionID sessionId = new SessionID( + request.QueryString["beginstring"] ?? "", + request.QueryString["sendercompid"] ?? "", + request.QueryString["targetcompid"] ?? ""); Session? sessionDetails = Session.LookupSession(sessionId); if (sessionDetails == null) throw new Exception("Session not found"); bool confirm = false; @@ -248,7 +251,10 @@ private string ResetSessions(HttpListenerRequest request, StringBuilder pageBuil private string ResetSession(HttpListenerRequest request, StringBuilder pageBuilder) { - SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]); + SessionID sessionId = new SessionID( + request.QueryString["beginstring"] ?? "", + request.QueryString["sendercompid"] ?? "", + request.QueryString["targetcompid"] ?? ""); Session? sessionDetails = Session.LookupSession(sessionId); if (sessionDetails == null) throw new Exception("Session not found"); @@ -326,7 +332,10 @@ private string ProcessRoot(HttpListenerRequest request, StringBuilder pageBuilde private string SessionDetails(HttpListenerRequest request, StringBuilder pageBuilder) { - SessionID sessionId = new SessionID(request.QueryString["beginstring"], request.QueryString["sendercompid"], request.QueryString["targetcompid"]); + SessionID sessionId = new SessionID( + request.QueryString["beginstring"] ?? "", + request.QueryString["sendercompid"] ?? "", + request.QueryString["targetcompid"] ?? ""); Session? sessionDetails = Session.LookupSession(sessionId); if (sessionDetails == null) throw new Exception("Session not found"); diff --git a/QuickFIXn/SessionID.cs b/QuickFIXn/SessionID.cs index cef7203c0..55fc2cb98 100755 --- a/QuickFIXn/SessionID.cs +++ b/QuickFIXn/SessionID.cs @@ -1,4 +1,4 @@ - +#nullable enable using System; namespace QuickFix @@ -8,64 +8,36 @@ namespace QuickFix /// and a session qualifier. Sessions are also identified by FIX version so /// that it's possible to have multiple sessions to the same counterparty /// but using different FIX versions (and/or session qualifiers). - /// /// public class SessionID { #region Properties - public string BeginString - { - get { return beginString_; } - } + public string BeginString { get; } - public string SenderCompID - { - get { return senderCompID_; } - } + public string SenderCompID { get; } - public string SenderSubID - { - get { return senderSubID_; } - } + public string SenderSubID { get; } - public string SenderLocationID - { - get { return senderLocationID_; } - } + public string SenderLocationID { get; } - public string TargetCompID - { - get { return targetCompID_; } - } + public string TargetCompID { get; } - public string TargetSubID - { - get { return targetSubID_; } - } + public string TargetSubID { get; } - public string TargetLocationID - { - get { return targetLocationID_; } - } + public string TargetLocationID { get; } /// /// Session qualifier can be used to identify different sessions /// for the same target company ID. Session qualifiers can only be used /// with initiated sessions. They cannot be used with accepted sessions. /// - public string SessionQualifier - { - get { return sessionQualifier_; } - } + public string? SessionQualifier { get; } /// /// Returns whether session version is FIXT 1.1 or newer /// - public bool IsFIXT - { - get { return isFIXT_; } - } + public bool IsFIXT { get; } #endregion @@ -74,87 +46,64 @@ public bool IsFIXT #endregion #region Private Members - private string id_; - private string beginString_; - private string senderCompID_; - private string senderSubID_; - private string senderLocationID_; - private string targetCompID_; - private string targetSubID_; - private string targetLocationID_; - private string sessionQualifier_; - private bool isFIXT_; + private readonly string _id; #endregion - public SessionID(string beginString, string senderCompID, string senderSubID, string senderLocationID, string targetCompID, string targetSubID, string targetLocationID, string sessionQualifier) + public SessionID(string beginString, string senderCompId, string senderSubId, string senderLocationId, string targetCompId, string targetSubId, string targetLocationId, string? sessionQualifier = NOT_SET) { - if (beginString == null) - throw new ArgumentNullException("beginString"); - if (senderCompID == null) - throw new ArgumentNullException("senderCompID"); - if (targetCompID == null) - throw new ArgumentNullException("targetCompID"); - beginString_ = beginString; - senderCompID_ = senderCompID; - senderSubID_ = senderSubID; - senderLocationID_ = senderLocationID; - targetCompID_ = targetCompID; - targetSubID_ = targetSubID; - targetLocationID_ = targetLocationID; - sessionQualifier_ = sessionQualifier; - isFIXT_ = beginString_.StartsWith("FIXT", StringComparison.Ordinal); - - id_ = beginString_ + BeginString = beginString ?? throw new ArgumentNullException(nameof(beginString)); + SenderCompID = senderCompId ?? throw new ArgumentNullException(nameof(senderCompId)); + SenderSubID = senderSubId; + SenderLocationID = senderLocationId; + TargetCompID = targetCompId ?? throw new ArgumentNullException(nameof(targetCompId)); + TargetSubID = targetSubId; + TargetLocationID = targetLocationId; + SessionQualifier = sessionQualifier; + IsFIXT = BeginString.StartsWith("FIXT", StringComparison.Ordinal); + + _id = BeginString + ":" - + senderCompID_ - + (IsSet(senderSubID_) ? "/" + senderSubID_ : "") - + (IsSet(senderLocationID_) ? "/" + senderLocationID_ : "") + + SenderCompID + + (IsSet(SenderSubID) ? "/" + SenderSubID : "") + + (IsSet(SenderLocationID) ? "/" + SenderLocationID : "") + "->" - + targetCompID_ - + (IsSet(targetSubID_) ? "/" + targetSubID_ : "") - + (IsSet(targetLocationID_) ? "/" + targetLocationID_ : ""); - if (null != sessionQualifier_ && sessionQualifier_.Length > 0) - id_ += ":" + sessionQualifier_; + + TargetCompID + + (IsSet(TargetSubID) ? "/" + TargetSubID : "") + + (IsSet(TargetLocationID) ? "/" + TargetLocationID : ""); + if (SessionQualifier is not null && SessionQualifier.Length > 0) + _id += ":" + SessionQualifier; } - public SessionID(string beginString, string senderCompID, string targetCompID) - : this(beginString, senderCompID, targetCompID, NOT_SET) - { } - - public SessionID(string beginString, string senderCompID, string senderSubID, string targetCompID, string targetSubID) - : this(beginString, senderCompID, senderSubID, NOT_SET, targetCompID, targetSubID, NOT_SET, NOT_SET) - { } - - public SessionID(string beginString, string senderCompID, string senderSubID, string senderLocationID, string targetCompID, string targetSubID, string targetLocationID) - : this(beginString, senderCompID, senderSubID, senderLocationID, targetCompID, targetSubID, targetLocationID, NOT_SET) + public SessionID(string beginString, string senderCompId, string senderSubId, string targetCompId, string targetSubId) + : this(beginString, senderCompId, senderSubId, senderLocationId: NOT_SET, targetCompId, targetSubId, targetLocationId: NOT_SET) { } - public SessionID(string beginString, string senderCompID, string targetCompID, string sessionQualifier) - : this(beginString, senderCompID, NOT_SET, NOT_SET, targetCompID, NOT_SET, NOT_SET, sessionQualifier) + public SessionID(string beginString, string senderCompId, string targetCompId, string sessionQualifier = NOT_SET) + : this(beginString, senderCompId, senderSubId: NOT_SET, senderLocationId: NOT_SET, targetCompId, targetSubId: NOT_SET, targetLocationId: NOT_SET, sessionQualifier) { } - public static bool IsSet(string value) + public static bool IsSet(string? value) { return value != null && value != NOT_SET; } public override string ToString() { - return id_; + return _id; } public override int GetHashCode() { - return id_.GetHashCode(); + return _id.GetHashCode(); } - public override bool Equals(object obj) + public override bool Equals(object? obj) { if (obj == null || GetType() != obj.GetType()) return false; SessionID rhs = (SessionID)obj; - return id_.Equals(rhs.id_); + return _id.Equals(rhs._id); } } } diff --git a/QuickFIXn/SessionSchedule.cs b/QuickFIXn/SessionSchedule.cs index 7e4b54d61..ebb8390df 100755 --- a/QuickFIXn/SessionSchedule.cs +++ b/QuickFIXn/SessionSchedule.cs @@ -1,47 +1,48 @@ - +#nullable enable using System; + namespace QuickFix { public class SessionSchedule { - public System.TimeSpan StartTime { get; private set; } - public System.TimeSpan EndTime { get; private set; } + public TimeSpan? StartTime { get; } + public TimeSpan? EndTime { get; } - public bool WeeklySession { get; private set; } - public System.DayOfWeek StartDay { get; private set; } - public System.DayOfWeek EndDay { get; private set; } + public bool WeeklySession { get; } + public DayOfWeek? StartDay { get; } + public DayOfWeek? EndDay { get; } - public bool NonStopSession { get; private set; } + public bool NonStopSession { get; } - public bool UseLocalTime { get; private set; } - public System.TimeZoneInfo TimeZone { get; private set; } + public bool UseLocalTime { get; } + public TimeZoneInfo? TimeZone { get; } /// /// Returns true if testtime is in a different and newer session than old time /// (or more explicitly: oldtime <= some EndTime < testtime) /// - /// - /// + /// + /// /// - public bool IsNewSession(DateTime oldtime_utc, DateTime testtime_utc) + public bool IsNewSession(DateTime oldtimeUtc, DateTime testtimeUtc) { if (NonStopSession) { return false; } - if (oldtime_utc.Kind != System.DateTimeKind.Utc) - throw new System.ArgumentException("Only UTC time is supported", "oldtime"); - if (testtime_utc.Kind != System.DateTimeKind.Utc) - throw new System.ArgumentException("Only UTC time is supported", "testtime"); + if (oldtimeUtc.Kind != DateTimeKind.Utc) + throw new ArgumentException("Only UTC time is supported", nameof(oldtimeUtc)); + if (testtimeUtc.Kind != DateTimeKind.Utc) + throw new ArgumentException("Only UTC time is supported", nameof(testtimeUtc)); - DateTime old = AdjustUtcDateTime(oldtime_utc); - DateTime test = AdjustUtcDateTime(testtime_utc); + DateTime old = AdjustUtcDateTime(oldtimeUtc); + DateTime test = AdjustUtcDateTime(testtimeUtc); if (DateTime.Compare(old, test) < 0) // old is earlier than test { - DateTime nextend = NextEndTime(oldtime_utc); + DateTime nextend = NextEndTime(oldtimeUtc); return (DateTime.Compare(old, nextend) <= 0) && (DateTime.Compare(nextend, test) < 0); } @@ -55,28 +56,23 @@ public bool IsNewSession(DateTime oldtime_utc, DateTime testtime_utc) /// public DateTime AdjustUtcDateTime(DateTime utc) { - if (utc.Kind != System.DateTimeKind.Utc) - throw new System.ArgumentException("Only UTC time is supported", "time"); + if (utc.Kind != DateTimeKind.Utc) + throw new ArgumentException("Only UTC time is supported", nameof(utc)); if(UseLocalTime) return utc.ToLocalTime(); - else if (TimeZone==null) - return utc; - else - return System.TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZone); + + return TimeZone==null ? utc : TimeZoneInfo.ConvertTimeFromUtc(utc, TimeZone); } - public bool IsSessionTime(System.DateTime utc) + public bool IsSessionTime(DateTime utc) { - if (utc.Kind != System.DateTimeKind.Utc) - throw new System.ArgumentException("Only UTC time is supported", "time"); + if (utc.Kind != DateTimeKind.Utc) + throw new ArgumentException("Only UTC time is supported", nameof(utc)); - System.DateTime adjusted = AdjustUtcDateTime(utc); + DateTime adjusted = AdjustUtcDateTime(utc); - if (WeeklySession) - return CheckDay(adjusted); - else - return CheckTime(adjusted.TimeOfDay); + return WeeklySession ? CheckDay(adjusted) : CheckTime(adjusted.TimeOfDay); } /// @@ -87,19 +83,19 @@ public bool IsSessionTime(System.DateTime utc) public DateTime NextEndTime(DateTime utc) { if (NonStopSession) - { throw new NotSupportedException("NonStopSession"); - } + + TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null"); if (utc.Kind != DateTimeKind.Utc) - throw new ArgumentException("Only UTC time is supported", "time"); + throw new ArgumentException("Only UTC time is supported", nameof(utc)); DateTime d = AdjustUtcDateTime(utc); DateTime end = DateTime.MinValue; if (WeeklySession) { - end = new DateTime(d.Year, d.Month, d.Day, EndTime.Hours, EndTime.Minutes, EndTime.Seconds, d.Kind); + end = new DateTime(d.Year, d.Month, d.Day, vEndTime.Hours, vEndTime.Minutes, vEndTime.Seconds, d.Kind); while (end.DayOfWeek != EndDay) end = end.AddDays(1); if (DateTime.Compare(d, end) > 0) // d is later than end @@ -107,7 +103,7 @@ public DateTime NextEndTime(DateTime utc) } else { - end = new DateTime(d.Year, d.Month, d.Day, EndTime.Hours, EndTime.Minutes, EndTime.Seconds, d.Kind); + end = new DateTime(d.Year, d.Month, d.Day, vEndTime.Hours, vEndTime.Minutes, vEndTime.Seconds, d.Kind); if (DateTime.Compare(d, end) > 0) // d is later than end end = end.AddDays(1); } @@ -115,83 +111,48 @@ public DateTime NextEndTime(DateTime utc) return end; } - // TODO: consider removing this function in v2.0, as it's not used. - /// - /// Return the latest EndTime (in UTC) before time. - /// - /// - /// - public DateTime LastEndTime(DateTime utc) - { - if (NonStopSession) - { - throw new NotSupportedException("NonStopSession"); - } - - if (utc.Kind != DateTimeKind.Utc) - throw new ArgumentException("Only UTC time is supported", "time"); - - DateTime n = NextEndTime(utc); - if (WeeklySession) - n = n.AddDays(-7); - else - n = n.AddDays(-1); - - if (UseLocalTime) - return n.ToUniversalTime(); - if (TimeZone != null) - return TimeZoneInfo.ConvertTimeBySystemTimeZoneId(n, this.TimeZone.Id, "UTC"); - return n; - } - /// /// return true if time falls within StartTime/EndTime /// /// /// - private bool CheckDay(System.DateTime time) + private bool CheckDay(DateTime time) { if (NonStopSession) - { throw new InvalidOperationException("NonStopSession is set -- this should never be called."); - } - if (StartDay < EndDay) + + DayOfWeek vStartDay = StartDay ?? throw new QuickFix.ConfigError("StartDay is null"); + DayOfWeek vEndDay = EndDay ?? throw new QuickFix.ConfigError("EndDay is null"); + TimeSpan vStartTime = StartTime ?? throw new QuickFix.ConfigError("StartTime is null"); + TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null"); + + if (vStartDay < vEndDay) { - if (time.DayOfWeek < StartDay || time.DayOfWeek > EndDay) - { + if (time.DayOfWeek < vStartDay || time.DayOfWeek > vEndDay) return false; - } - else if (time.DayOfWeek < EndDay) - { - return (StartDay < time.DayOfWeek) || (StartTime.CompareTo(time.TimeOfDay) <= 0); - } - else - { - return (time.DayOfWeek < EndDay) || (EndTime.CompareTo(time.TimeOfDay) >= 0); - } + + if (time.DayOfWeek < vEndDay) + return (vStartDay < time.DayOfWeek) || (vStartTime.CompareTo(time.TimeOfDay) <= 0); + + return (time.DayOfWeek < vEndDay) || (vEndTime.CompareTo(time.TimeOfDay) >= 0); } - if (EndDay < StartDay) + if (vEndDay < vStartDay) { - if (EndDay < time.DayOfWeek && time.DayOfWeek < StartDay) - { + if (vEndDay < time.DayOfWeek && time.DayOfWeek < vStartDay) return false; - } - else if (time.DayOfWeek < StartDay) - { - return (time.DayOfWeek < EndDay) || (EndTime.CompareTo(time.TimeOfDay) >= 0); - } - else - { - return (time.DayOfWeek > StartDay) || (StartTime.CompareTo(time.TimeOfDay) <= 0); - } + + if (time.DayOfWeek < vStartDay) + return (time.DayOfWeek < vEndDay) || (vEndTime.CompareTo(time.TimeOfDay) >= 0); + + return (time.DayOfWeek > vStartDay) || (vStartTime.CompareTo(time.TimeOfDay) <= 0); } //start day must be same as end day - if (StartTime >= EndTime) - return time.DayOfWeek != StartDay || CheckTime(time.TimeOfDay); - else - return time.DayOfWeek == StartDay && CheckTime(time.TimeOfDay); + if (vStartTime >= vEndTime) + return time.DayOfWeek != vStartDay || CheckTime(time.TimeOfDay); + + return time.DayOfWeek == vStartDay && CheckTime(time.TimeOfDay); } /// @@ -199,22 +160,24 @@ private bool CheckDay(System.DateTime time) /// /// /// - private bool CheckTime(System.TimeSpan time) + private bool CheckTime(TimeSpan time) { if (NonStopSession) - { return true; - } - if (StartTime.CompareTo(EndTime) < 0) + TimeSpan vStartTime = StartTime ?? throw new QuickFix.ConfigError("StartTime is null"); + TimeSpan vEndTime = EndTime ?? throw new QuickFix.ConfigError("EndTime is null"); + + if (vStartTime.CompareTo(vEndTime) < 0) { - return (time.CompareTo(StartTime) >= 0 && - time.CompareTo(EndTime) <= 0); + return (time.CompareTo(vStartTime) >= 0 && + time.CompareTo(vEndTime) <= 0); } - else if (StartTime.CompareTo(EndTime) > 0) + + if (vStartTime.CompareTo(vEndTime) > 0) { - return (time.CompareTo(StartTime) >= 0 || - time.CompareTo(EndTime) <= 0); + return time.CompareTo(vStartTime) >= 0 || + time.CompareTo(vEndTime) <= 0; } return true; @@ -226,23 +189,16 @@ private bool CheckTime(System.TimeSpan time) public SessionSchedule(QuickFix.Dictionary settings) { if (settings.Has(SessionSettings.NON_STOP_SESSION)) - { NonStopSession = settings.GetBool(SessionSettings.NON_STOP_SESSION); - } + if (NonStopSession) - { return; - } if (!settings.Has(SessionSettings.START_DAY) && settings.Has(SessionSettings.END_DAY)) - { throw new QuickFix.ConfigError("EndDay used without StartDay"); - } if (settings.Has(SessionSettings.START_DAY) && !settings.Has(SessionSettings.END_DAY)) - { throw new QuickFix.ConfigError("StartDay used without EndDay"); - } if (settings.Has(SessionSettings.START_DAY) && settings.Has(SessionSettings.END_DAY)) { @@ -264,18 +220,18 @@ public SessionSchedule(QuickFix.Dictionary settings) SessionSettings.TIME_ZONE + " conflicts with " + SessionSettings.USE_LOCAL_TIME); } string id = settings.GetString(SessionSettings.TIME_ZONE); - TimeZone = System.TimeZoneInfo.FindSystemTimeZoneById(id); + TimeZone = TimeZoneInfo.FindSystemTimeZoneById(id); } try { - this.StartTime = System.TimeSpan.Parse( + StartTime = TimeSpan.Parse( settings.GetString(SessionSettings.START_TIME)); - this.EndTime = System.TimeSpan.Parse( + EndTime = TimeSpan.Parse( settings.GetString(SessionSettings.END_TIME)); } - catch (System.FormatException e) + catch (FormatException e) { throw new ConfigError(e.Message); } diff --git a/QuickFIXn/SessionSettings.cs b/QuickFIXn/SessionSettings.cs index 7f87d8364..abefde561 100755 --- a/QuickFIXn/SessionSettings.cs +++ b/QuickFIXn/SessionSettings.cs @@ -84,8 +84,8 @@ public class SessionSettings #region Private Members - private QuickFix.Dictionary defaults_ = new QuickFix.Dictionary(); - private System.Collections.Generic.Dictionary settings_ = new Dictionary(); + private QuickFix.Dictionary _defaults = new(); + private readonly System.Collections.Generic.Dictionary _settings = new(); #endregion @@ -101,7 +101,7 @@ public SessionSettings(string file) } catch (System.Exception e) { - throw new ConfigError("File " + file + " not found (" + e.Message + ")"); + throw new ConfigError($"File {file} not found ({e.Message})"); } } @@ -121,9 +121,9 @@ protected void Load(TextReader conf) //---- load the DEFAULT section LinkedList section = settings.Get("DEFAULT"); - QuickFix.Dictionary def = new QuickFix.Dictionary(); + QuickFix.Dictionary def = new(); if (section.Count > 0) - def = section.First.Value; + def = section.First!.Value; Set(def); //---- load each SESSION section @@ -133,29 +133,29 @@ protected void Load(TextReader conf) dict.Merge(def); string sessionQualifier = SessionID.NOT_SET; - string senderSubID = SessionID.NOT_SET; - string senderLocID = SessionID.NOT_SET; - string targetSubID = SessionID.NOT_SET; - string targetLocID = SessionID.NOT_SET; + string senderSubId = SessionID.NOT_SET; + string senderLocId = SessionID.NOT_SET; + string targetSubId = SessionID.NOT_SET; + string targetLocId = SessionID.NOT_SET; if (dict.Has(SESSION_QUALIFIER)) sessionQualifier = dict.GetString(SESSION_QUALIFIER); if (dict.Has(SENDERSUBID)) - senderSubID = dict.GetString(SENDERSUBID); + senderSubId = dict.GetString(SENDERSUBID); if (dict.Has(SENDERLOCID)) - senderLocID = dict.GetString(SENDERLOCID); + senderLocId = dict.GetString(SENDERLOCID); if (dict.Has(TARGETSUBID)) - targetSubID = dict.GetString(TARGETSUBID); + targetSubId = dict.GetString(TARGETSUBID); if (dict.Has(TARGETLOCID)) - targetLocID = dict.GetString(TARGETLOCID); - SessionID sessionID = new SessionID(dict.GetString(BEGINSTRING), dict.GetString(SENDERCOMPID), senderSubID, senderLocID, dict.GetString(TARGETCOMPID), targetSubID, targetLocID, sessionQualifier); - Set(sessionID, dict); + targetLocId = dict.GetString(TARGETLOCID); + SessionID sessionId = new SessionID(dict.GetString(BEGINSTRING), dict.GetString(SENDERCOMPID), senderSubId, senderLocId, dict.GetString(TARGETCOMPID), targetSubId, targetLocId, sessionQualifier); + Set(sessionId, dict); } } - public bool Has(SessionID sessionID) + public bool Has(SessionID sessionId) { - return settings_.ContainsKey(sessionID); + return _settings.ContainsKey(sessionId); } /// @@ -164,68 +164,67 @@ public bool Has(SessionID sessionID) /// Dictionary of settings from the [DEFAULT] section public QuickFix.Dictionary Get() { - return defaults_; + return _defaults; } /// /// Get a dictionary for a session /// - /// the ID of the session + /// the ID of the session /// Dictionary of settings from the [SESSION] section for the given SessionID - public Dictionary Get(SessionID sessionID) + public Dictionary Get(SessionID sessionId) { - Dictionary dict; - if (!settings_.TryGetValue(sessionID, out dict)) - throw new ConfigError("Session '" + sessionID + "' not found"); + if (!_settings.TryGetValue(sessionId, out var dict)) + throw new ConfigError($"Session '{sessionId}' not found"); return dict; } public void Set(QuickFix.Dictionary defaults) { - defaults_ = defaults; - foreach (KeyValuePair entry in settings_) - entry.Value.Merge(defaults_); + _defaults = defaults; + foreach (KeyValuePair entry in _settings) + entry.Value.Merge(_defaults); } /// /// Remove existing session config from the settings /// - /// ID of session for which config is to be removed + /// ID of session for which config is to be removed /// true if removed, false if config for the session does not exist - public bool Remove(SessionID sessionID) + public bool Remove(SessionID sessionId) { - return settings_.Remove(sessionID); + return _settings.Remove(sessionId); } /// /// Add new session config /// - /// ID of session for which to add config + /// ID of session for which to add config /// session config - public void Set(SessionID sessionID, QuickFix.Dictionary settings) + public void Set(SessionID sessionId, QuickFix.Dictionary settings) { - if (Has(sessionID)) - throw new ConfigError("Duplicate Session " + sessionID.ToString()); - settings.SetString(BEGINSTRING, sessionID.BeginString); - settings.SetString(SENDERCOMPID, sessionID.SenderCompID); - if (SessionID.IsSet(sessionID.SenderSubID)) - settings.SetString(SENDERSUBID, sessionID.SenderSubID); - if (SessionID.IsSet(sessionID.SenderLocationID)) - settings.SetString(SENDERLOCID, sessionID.SenderLocationID); - settings.SetString(TARGETCOMPID, sessionID.TargetCompID); - if (SessionID.IsSet(sessionID.TargetSubID)) - settings.SetString(TARGETSUBID, sessionID.TargetSubID); - if (SessionID.IsSet(sessionID.TargetLocationID)) - settings.SetString(TARGETLOCID, sessionID.TargetLocationID); - settings.Merge(defaults_); + if (Has(sessionId)) + throw new ConfigError($"Duplicate Session {sessionId}"); + settings.SetString(BEGINSTRING, sessionId.BeginString); + settings.SetString(SENDERCOMPID, sessionId.SenderCompID); + if (SessionID.IsSet(sessionId.SenderSubID)) + settings.SetString(SENDERSUBID, sessionId.SenderSubID); + if (SessionID.IsSet(sessionId.SenderLocationID)) + settings.SetString(SENDERLOCID, sessionId.SenderLocationID); + settings.SetString(TARGETCOMPID, sessionId.TargetCompID); + if (SessionID.IsSet(sessionId.TargetSubID)) + settings.SetString(TARGETSUBID, sessionId.TargetSubID); + if (SessionID.IsSet(sessionId.TargetLocationID)) + settings.SetString(TARGETLOCID, sessionId.TargetLocationID); + settings.Merge(_defaults); Validate(settings); - settings_[sessionID] = settings; + _settings[sessionId] = settings; } public HashSet GetSessions() { HashSet result = new HashSet(); - foreach (KeyValuePair entry in settings_) + foreach (KeyValuePair entry in _settings) result.Add(entry.Key); return result; } @@ -235,15 +234,15 @@ public override string ToString() System.Text.StringBuilder s = new System.Text.StringBuilder(); s.AppendLine("[DEFAULT]"); - foreach (System.Collections.Generic.KeyValuePair entry in defaults_) + foreach (System.Collections.Generic.KeyValuePair entry in _defaults) s.Append(entry.Key).Append('=').AppendLine(entry.Value); - foreach (KeyValuePair entry in settings_) + foreach (KeyValuePair entry in _settings) { s.AppendLine().AppendLine("[SESSION]"); foreach (System.Collections.Generic.KeyValuePair kvp in entry.Value) { - if (defaults_.Has(kvp.Key) && defaults_.GetString(kvp.Key).Equals(kvp.Value)) + if (_defaults.Has(kvp.Key) && _defaults.GetString(kvp.Key).Equals(kvp.Value)) continue; s.Append(kvp.Key).Append('=').AppendLine(kvp.Value); } @@ -262,13 +261,13 @@ protected void Validate(QuickFix.Dictionary dictionary) beginString != Values.BeginString_FIX44 && beginString != Values.BeginString_FIXT11) { - throw new ConfigError(BEGINSTRING + " (" + beginString + ") must be FIX.4.0 to FIX.4.4 or FIXT.1.1"); + throw new ConfigError($"{BEGINSTRING} ({beginString}) must be FIX.4.0 to FIX.4.4 or FIXT.1.1"); } string connectionType = dictionary.GetString(CONNECTION_TYPE); if (!"initiator".Equals(connectionType) && !"acceptor".Equals(connectionType)) { - throw new ConfigError(CONNECTION_TYPE + " must be 'initiator' or 'acceptor'"); + throw new ConfigError($"{CONNECTION_TYPE} must be 'initiator' or 'acceptor'"); } } } diff --git a/QuickFIXn/Settings.cs b/QuickFIXn/Settings.cs index 1219dc222..1cd517ea1 100755 --- a/QuickFIXn/Settings.cs +++ b/QuickFIXn/Settings.cs @@ -1,16 +1,17 @@ -using System.Collections.Generic; +#nullable enable +using System.Collections.Generic; namespace QuickFix { public class Settings { - private LinkedList sections_ = new LinkedList(); + private readonly LinkedList _sections = new(); public Settings(System.IO.TextReader conf) { - QuickFix.Dictionary currentSection = null; + QuickFix.Dictionary? currentSection = null; - string line = null; + string? line; while ((line = conf.ReadLine()) != null) { line = line.Trim(); @@ -18,7 +19,8 @@ public Settings(System.IO.TextReader conf) { continue; } - else if (IsSection(line)) + + if (IsSection(line)) { currentSection = Add(new Dictionary(SplitSection(line))); } @@ -56,12 +58,12 @@ public static bool IsSection(string s) { if (s.Length < 2) return false; - return s[0] == '[' && s[s.Length - 1] == ']'; + return s[0] == '[' && s[^1] == ']'; } public QuickFix.Dictionary Add(QuickFix.Dictionary section) { - sections_.AddLast(section); + _sections.AddLast(section); return section; } @@ -73,8 +75,8 @@ public QuickFix.Dictionary Add(QuickFix.Dictionary section) /// public LinkedList Get(string sectionName) { - LinkedList result = new LinkedList(); - foreach (QuickFix.Dictionary dict in sections_) + LinkedList result = new(); + foreach (QuickFix.Dictionary dict in _sections) if (sectionName.ToUpperInvariant() == dict.Name.ToUpperInvariant()) result.AddLast(dict); return result; diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index e4d27b1a9..86af9145d 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -42,6 +42,10 @@ What's New * Session: Logon() and Logout() made internal and renamed. No one should be using these. * SessionState: ctor now requires a MessageStore. (Existing callers used an object initializer anyway) * Many protected functions were altered, but probably no user code is touching them +* #827 - cleanup/nullable-ize StreamFactory, SessionID, Settings, SessionSettings, SessionSchedule (gbirchmeier) + * StreamFactory: privatized a lot of members; I don't think users are inheriting from this + * SessionSchedule: remove unused LastEndTime() + **Non-breaking changes** * #400 - added DDTool, a C#-based codegen, and deleted Ruby-based generator (gbirchmeier) diff --git a/UnitTests/SessionScheduleTests.cs b/UnitTests/SessionScheduleTests.cs index 1cd70a4a1..b5854f4d0 100755 --- a/UnitTests/SessionScheduleTests.cs +++ b/UnitTests/SessionScheduleTests.cs @@ -353,101 +353,6 @@ public void testTimeZone() Assert.IsFalse(sched.IsSessionTime(new DateTime(2011, 10, 17, 20, 0, 1, DateTimeKind.Utc))); } - [Test] - public void testLastEndTime_takesUtcOnly() - { - QuickFix.Dictionary settings = new QuickFix.Dictionary(); - settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00"); - settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00"); - - QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings); - - Assert.Throws( - delegate { sched.LastEndTime(new DateTime(2012, 10, 18, 12, 00, 00, DateTimeKind.Local)); }); - Assert.Throws( - delegate { sched.LastEndTime(new DateTime(2012, 10, 18, 12, 00, 00, DateTimeKind.Unspecified)); }); - } - - [Test] - public void testLastEndTime_DailySessions() - { - QuickFix.Dictionary settings = new QuickFix.Dictionary(); - settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00"); - settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00"); - QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings); - - DateTime thisDayEnd = new DateTime(2013, 02, 05, 16, 00, 00, DateTimeKind.Utc); - DateTime prevDayEnd = new DateTime(2013, 02, 04, 16, 00, 00, DateTimeKind.Utc); - - // before starttime - Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc))); - // during session - Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 10, 00, 00, DateTimeKind.Utc))); - // equals endtime - Assert.AreEqual(prevDayEnd, sched.LastEndTime(thisDayEnd)); - // after endtime - Assert.AreEqual(thisDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 17, 00, 00, DateTimeKind.Utc))); - - // ========== - // Settings file is specified in a zone (est, -5) - settings = new QuickFix.Dictionary(); - settings.SetString(QuickFix.SessionSettings.START_TIME, "04:30:00"); // 09:30:00 utc - settings.SetString(QuickFix.SessionSettings.END_TIME, "11:00:00"); // 16:00:00 utc - settings.SetString(QuickFix.SessionSettings.TIME_ZONE, EASTERN_STANDARD_TIME_ZONE_ID); //-5 - sched = new QuickFix.SessionSchedule(settings); - - // before starttime - Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc))); - // during session - Assert.AreEqual(prevDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 10, 00, 00, DateTimeKind.Utc))); - // equals endtime - Assert.AreEqual(prevDayEnd, sched.LastEndTime(thisDayEnd)); - // after endtime - Assert.AreEqual(thisDayEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 17, 00, 00, DateTimeKind.Utc))); - } - - [Test] - public void testLastEndTime_WeeklySessions() - { - QuickFix.Dictionary settings = new QuickFix.Dictionary(); - settings.SetString(QuickFix.SessionSettings.START_TIME, "09:30:00"); - settings.SetString(QuickFix.SessionSettings.END_TIME, "16:00:00"); - settings.SetDay(QuickFix.SessionSettings.START_DAY, System.DayOfWeek.Monday); - settings.SetDay(QuickFix.SessionSettings.END_DAY, System.DayOfWeek.Friday); - QuickFix.SessionSchedule sched = new QuickFix.SessionSchedule(settings); - - DateTime thisWeekEnd = new DateTime(2013, 02, 08, 16, 00, 00, DateTimeKind.Utc); - DateTime prevWeekEnd = new DateTime(2013, 02, 01, 16, 00, 00, DateTimeKind.Utc); - - // before starttime - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 04, 08, 00, 00, DateTimeKind.Utc))); - // during session - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc))); - // equals endtime - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(thisWeekEnd)); - // after endtime - Assert.AreEqual(thisWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 08, 17, 00, 00, DateTimeKind.Utc))); - - // ========== - // Settings file is specified in a zone (est, -5) - settings = new QuickFix.Dictionary(); - settings.SetString(QuickFix.SessionSettings.START_TIME, "04:30:00"); // 09:30:00 utc - settings.SetString(QuickFix.SessionSettings.END_TIME, "11:00:00"); // 16:00:00 utc - settings.SetString(QuickFix.SessionSettings.TIME_ZONE, EASTERN_STANDARD_TIME_ZONE_ID); //-5 - settings.SetDay(QuickFix.SessionSettings.START_DAY, System.DayOfWeek.Monday); - settings.SetDay(QuickFix.SessionSettings.END_DAY, System.DayOfWeek.Friday); - sched = new QuickFix.SessionSchedule(settings); - - // before starttime - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 04, 08, 00, 00, DateTimeKind.Utc))); - // during session - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 05, 08, 00, 00, DateTimeKind.Utc))); - // equals endtime - Assert.AreEqual(prevWeekEnd, sched.LastEndTime(thisWeekEnd)); - // after endtime - Assert.AreEqual(thisWeekEnd, sched.LastEndTime(new DateTime(2013, 02, 08, 17, 00, 00, DateTimeKind.Utc))); - } - [Test] public void testNextEndTime_takesUtcOnly() {