diff --git a/Common/Util/StreamReaderExtensions.cs b/Common/Util/StreamReaderExtensions.cs index af959e4392c7..1606ffc2aa5b 100644 --- a/Common/Util/StreamReaderExtensions.cs +++ b/Common/Util/StreamReaderExtensions.cs @@ -156,6 +156,37 @@ public static int GetInt32(this StreamReader stream, char delimiter = DefaultDel return isNegative ? result * -1 : result; } + /// + /// Gets an integer from a stream reader + /// + /// The data stream + /// The data delimiter character to use, default is ',' + /// The integer instance read + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static long GetInt64(this StreamReader stream, char delimiter = DefaultDelimiter) + { + var result = 0L; + var current = (char)stream.Read(); + + while (current == ' ') + { + current = (char)stream.Read(); + } + + var isNegative = current == '-'; + if (isNegative) + { + current = (char)stream.Read(); + } + + while (!(current == delimiter || current == '\n' || current == '\r' && (stream.Peek() != '\n' || stream.Read() == '\n') || current == NoMoreData || current == ' ')) + { + result = (current - '0') + result * 10L; + current = (char)stream.Read(); + } + return isNegative ? result * -1L : result; + } + private readonly static ConcurrentBag StringBuilders = new(); /// diff --git a/Tests/Common/Util/StreamReaderExtensionsTests.cs b/Tests/Common/Util/StreamReaderExtensionsTests.cs index b3fcf7232f56..e4d46125de6a 100644 --- a/Tests/Common/Util/StreamReaderExtensionsTests.cs +++ b/Tests/Common/Util/StreamReaderExtensionsTests.cs @@ -320,6 +320,54 @@ public void GetIntWithLineFeed() Assert.AreEqual(201900, smartStream.GetInt32()); } + [Test] + public void GetInt64() + { + var stream = $"1588291200426000,0,1588291202486000{Environment.NewLine}1588291205550000{Environment.NewLine}".ToStream(); + using var smartStream = new StreamReader(stream); + + Assert.AreEqual(1588291200426000, smartStream.GetInt64()); + Assert.AreEqual(0L, smartStream.GetInt64()); + Assert.AreEqual(1588291202486000, smartStream.GetInt64()); + Assert.AreEqual(1588291205550000, smartStream.GetInt64()); + } + + [Test] + public void GetNegativeInt64() + { + var stream = $"-1588291200426000,0,-1588291202486000{Environment.NewLine}-1588291205550000{Environment.NewLine}".ToStream(); + using var smartStream = new StreamReader(stream); + + Assert.AreEqual(-1588291200426000, smartStream.GetInt64()); + Assert.AreEqual(0L, smartStream.GetInt64()); + Assert.AreEqual(-1588291202486000, smartStream.GetInt64()); + Assert.AreEqual(-1588291205550000, smartStream.GetInt64()); + } + + [Test] + public void GetInt64WithCarriageReturnAndLineFeed() + { + var stream = "1588291200426000,0,1588291202486000\r\n1588291205550000\r\n".ToStream(); + using var smartStream = new StreamReader(stream); + + Assert.AreEqual(1588291200426000, smartStream.GetInt64()); + Assert.AreEqual(0L, smartStream.GetInt64()); + Assert.AreEqual(1588291202486000, smartStream.GetInt64()); + Assert.AreEqual(1588291205550000, smartStream.GetInt64()); + } + + [Test] + public void GetInt64WithLineFeed() + { + var stream = "1588291200426000,0,1588291202486000\n1588291205550000\n".ToStream(); + using var smartStream = new StreamReader(stream); + + Assert.AreEqual(1588291200426000, smartStream.GetInt64()); + Assert.AreEqual(0L, smartStream.GetInt64()); + Assert.AreEqual(1588291202486000, smartStream.GetInt64()); + Assert.AreEqual(1588291205550000, smartStream.GetInt64()); + } + [Parallelizable(ParallelScope.None)] [TestCase(typeof(TradeBar), typeof(TradeBarTest), TickType.Trade)] [TestCase(typeof(QuoteBar), typeof(QuoteBarTest), TickType.Quote)]