From 05214aaa54457e98f7dfa390be38a6ba64171a67 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 15 Oct 2021 11:32:25 +0200 Subject: [PATCH 01/16] S.IO.StringReader: Use ReadOnlySpan.IndexOfAny in ReadLine() for performance --- .../src/System/IO/StringReader.cs | 34 ++++++++----------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 35618daa455104..b2588538d6dc48 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -179,34 +179,30 @@ public override string ReadToEnd() { throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); } + if ((uint)_pos >= (uint)_length) + return null; - int i = _pos; - while (i < _length) + ReadOnlySpan remaining = _s.AsSpan(_pos); + int foundLineLength = remaining.IndexOfAny('\r', '\n'); + if (foundLineLength >= 0) { - char ch = _s[i]; - if (ch == '\r' || ch == '\n') + string result = _s.Substring(_pos, foundLineLength); + + char ch = remaining[foundLineLength]; + _pos += foundLineLength + 1; + if (ch == '\r' && _pos < _length && _s[_pos] == '\n') { - string result = _s.Substring(_pos, i - _pos); - _pos = i + 1; - if (ch == '\r' && _pos < _length && _s[_pos] == '\n') - { - _pos++; - } - - return result; + _pos++; } - i++; + return result; } - - if (i > _pos) + else { - string result = _s.Substring(_pos, i - _pos); - _pos = i; + string result = _s.Substring(_pos, _length - _pos); + _pos = _length; return result; } - - return null; } #region Task based Async APIs From e160a7c50185cc15403b37599d369c889ba0eeb2 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 17 Oct 2021 13:40:41 +0200 Subject: [PATCH 02/16] Use throwhelper, add found line length 0 special case --- .../src/System/IO/StringReader.cs | 16 +++++++++------- .../src/System/ThrowHelper.cs | 6 ++++++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index b2588538d6dc48..29b45d69b0cd19 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -46,7 +46,7 @@ public override int Peek() { if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } if (_pos == _length) { @@ -63,7 +63,7 @@ public override int Read() { if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } if (_pos == _length) { @@ -98,7 +98,7 @@ public override int Read(char[] buffer, int index, int count) } if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } int n = _length - _pos; @@ -126,7 +126,7 @@ public override int Read(Span buffer) if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } int n = _length - _pos; @@ -150,7 +150,7 @@ public override string ReadToEnd() { if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } string s; @@ -177,7 +177,7 @@ public override string ReadToEnd() { if (_s == null) { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } if ((uint)_pos >= (uint)_length) return null; @@ -186,7 +186,9 @@ public override string ReadToEnd() int foundLineLength = remaining.IndexOfAny('\r', '\n'); if (foundLineLength >= 0) { - string result = _s.Substring(_pos, foundLineLength); + string result = foundLineLength == 0 + ? string.Empty + : _s.Substring(_pos, foundLineLength); char ch = remaining[foundLineLength]; _pos += foundLineLength + 1; diff --git a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs index e5f4e144dd4611..a5afac1d729aea 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs @@ -392,6 +392,12 @@ internal static void ThrowObjectDisposedException_FileClosed() throw new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed); } + [DoesNotReturn] + internal static void ThrowObjectDisposedException_ReaderClosed() + { + throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + } + [DoesNotReturn] internal static void ThrowObjectDisposedException(ExceptionResource resource) { From 5e915c591c0e37f2d1f234fc291f60418d916729 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 17 Oct 2021 16:32:40 +0200 Subject: [PATCH 03/16] replace Substring with new string(ReadOnlySpan...) --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 29b45d69b0cd19..e5299da5adea2c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -3,6 +3,7 @@ using System.Threading; using System.Threading.Tasks; +using Internal.Runtime.CompilerServices; namespace System.IO { @@ -188,7 +189,7 @@ public override string ReadToEnd() { string result = foundLineLength == 0 ? string.Empty - : _s.Substring(_pos, foundLineLength); + : new string(new ReadOnlySpan(ref Unsafe.AsRef(remaining.GetPinnableReference()), foundLineLength)); //_s.Substring(_pos, foundLineLength); char ch = remaining[foundLineLength]; _pos += foundLineLength + 1; @@ -201,7 +202,7 @@ public override string ReadToEnd() } else { - string result = _s.Substring(_pos, _length - _pos); + string result = new string(remaining); // _s.Substring(_pos, _length - _pos); _pos = _length; return result; } From c75a139b277e956baf2951c0c4d2311bd311b9db Mon Sep 17 00:00:00 2001 From: ntr Date: Mon, 18 Oct 2021 16:04:42 +0200 Subject: [PATCH 04/16] remove _length, use local s, drop unsafe use --- .../src/System/IO/StringReader.cs | 31 +++++++++---------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index e5299da5adea2c..13b21f9aa77872 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -3,7 +3,6 @@ using System.Threading; using System.Threading.Tasks; -using Internal.Runtime.CompilerServices; namespace System.IO { @@ -12,7 +11,6 @@ public class StringReader : TextReader { private string? _s; private int _pos; - private int _length; public StringReader(string s) { @@ -22,7 +20,6 @@ public StringReader(string s) } _s = s; - _length = s.Length; } public override void Close() @@ -34,7 +31,6 @@ protected override void Dispose(bool disposing) { _s = null; _pos = 0; - _length = 0; base.Dispose(disposing); } @@ -49,7 +45,7 @@ public override int Peek() { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if (_pos == _length) + if (_pos == _s.Length) { return -1; } @@ -66,7 +62,7 @@ public override int Read() { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if (_pos == _length) + if (_pos == _s.Length) { return -1; } @@ -102,7 +98,7 @@ public override int Read(char[] buffer, int index, int count) ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - int n = _length - _pos; + int n = _s.Length - _pos; if (n > 0) { if (n > count) @@ -130,7 +126,7 @@ public override int Read(Span buffer) ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - int n = _length - _pos; + int n = _s.Length - _pos; if (n > 0) { if (n > buffer.Length) @@ -161,10 +157,10 @@ public override string ReadToEnd() } else { - s = _s.Substring(_pos, _length - _pos); + s = _s.Substring(_pos, _s.Length - _pos); } - _pos = _length; + _pos = _s.Length; return s; } @@ -176,24 +172,25 @@ public override string ReadToEnd() // public override string? ReadLine() { - if (_s == null) + string? s = _s; + if (s == null) { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if ((uint)_pos >= (uint)_length) + if ((uint)_pos >= (uint)s.Length) return null; - ReadOnlySpan remaining = _s.AsSpan(_pos); + ReadOnlySpan remaining = s.AsSpan(_pos); int foundLineLength = remaining.IndexOfAny('\r', '\n'); if (foundLineLength >= 0) { string result = foundLineLength == 0 ? string.Empty - : new string(new ReadOnlySpan(ref Unsafe.AsRef(remaining.GetPinnableReference()), foundLineLength)); //_s.Substring(_pos, foundLineLength); + : new string(remaining.Slice(0, foundLineLength)); char ch = remaining[foundLineLength]; _pos += foundLineLength + 1; - if (ch == '\r' && _pos < _length && _s[_pos] == '\n') + if (ch == '\r' && _pos < s.Length && s[_pos] == '\n') { _pos++; } @@ -202,8 +199,8 @@ public override string ReadToEnd() } else { - string result = new string(remaining); // _s.Substring(_pos, _length - _pos); - _pos = _length; + string result = new string(remaining); + _pos = s.Length; return result; } } From 4f78e7e090fe0064d469cedf57e9b94fee7686b2 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 21 Nov 2021 11:37:55 +0100 Subject: [PATCH 05/16] address stephentoub feedback --- .../src/System/IO/StringReader.cs | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 13b21f9aa77872..a28d344d1949fb 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -41,16 +41,19 @@ protected override void Dispose(bool disposing) // public override int Peek() { - if (_s == null) + string? s = _s; + if (s == null) { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if (_pos == _s.Length) + + int pos = _pos; + if ((uint)pos < s.Length) { - return -1; + return s[pos]; } - return _s[_pos]; + return -1; } // Reads the next character from the underlying string. The returned value @@ -177,10 +180,11 @@ public override string ReadToEnd() { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if ((uint)_pos >= (uint)s.Length) + var pos = _pos; + if ((uint)pos >= (uint)s.Length) return null; - ReadOnlySpan remaining = s.AsSpan(_pos); + ReadOnlySpan remaining = s.AsSpan(pos); int foundLineLength = remaining.IndexOfAny('\r', '\n'); if (foundLineLength >= 0) { @@ -189,14 +193,23 @@ public override string ReadToEnd() : new string(remaining.Slice(0, foundLineLength)); char ch = remaining[foundLineLength]; - _pos += foundLineLength + 1; - if (ch == '\r' && _pos < s.Length && s[_pos] == '\n') + pos += foundLineLength + 1; + if (ch == '\r') { - _pos++; + if ((uint)pos < s.Length && s[pos] == '\n') + { + ++pos; + } } - + _pos = pos; return result; } + else if (remaining.Length == s.Length) + { + // Return source string if only one line avoiding allocation + _pos = s.Length; + return s; + } else { string result = new string(remaining); From 01dd19e75c9e910d6ad137b97680f7f51089088c Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 21 Nov 2021 11:41:19 +0100 Subject: [PATCH 06/16] change Read() similar to Peek() --- .../src/System/IO/StringReader.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index a28d344d1949fb..cdd8ce4a73f723 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -61,16 +61,20 @@ public override int Peek() // public override int Read() { - if (_s == null) + string? s = _s; + if (s == null) { ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); } - if (_pos == _s.Length) + + int pos = _pos; + if ((uint)pos < s.Length) { - return -1; + _pos++; + return s[pos]; } - return _s[_pos++]; + return -1; } // Reads a block of characters. This method will read up to count From e596b6af5125601523d7758d90a6f7d3daa9a6bd Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 28 Nov 2021 11:51:52 +0100 Subject: [PATCH 07/16] more nits --- .../StringReader/StringReader.CtorTests.cs | 2 +- .../src/System/IO/StringReader.cs | 24 ++++++++++++------- .../src/System/ThrowHelper.cs | 6 ----- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/libraries/System.IO/tests/StringReader/StringReader.CtorTests.cs b/src/libraries/System.IO/tests/StringReader/StringReader.CtorTests.cs index 8ff84e80c06950..9e500923164f38 100644 --- a/src/libraries/System.IO/tests/StringReader/StringReader.CtorTests.cs +++ b/src/libraries/System.IO/tests/StringReader/StringReader.CtorTests.cs @@ -59,7 +59,7 @@ public static void ReadLine() using (StringReader sr = new StringReader(str1)) { - Assert.Equal(str1, sr.ReadLine()); + Assert.Same(str1, sr.ReadLine()); } using (StringReader sr = new StringReader(str2)) { diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index cdd8ce4a73f723..c051d8a420eed3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Diagnostics.CodeAnalysis; using System.Threading; using System.Threading.Tasks; @@ -44,7 +45,7 @@ public override int Peek() string? s = _s; if (s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } int pos = _pos; @@ -64,7 +65,7 @@ public override int Read() string? s = _s; if (s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } int pos = _pos; @@ -102,7 +103,7 @@ public override int Read(char[] buffer, int index, int count) } if (_s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } int n = _s.Length - _pos; @@ -130,7 +131,7 @@ public override int Read(Span buffer) if (_s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } int n = _s.Length - _pos; @@ -154,7 +155,7 @@ public override string ReadToEnd() { if (_s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } string s; @@ -164,7 +165,7 @@ public override string ReadToEnd() } else { - s = _s.Substring(_pos, _s.Length - _pos); + s = _s.Substring(_pos); } _pos = _s.Length; @@ -182,7 +183,7 @@ public override string ReadToEnd() string? s = _s; if (s == null) { - ThrowHelper.ThrowObjectDisposedException_ReaderClosed(); + ThrowObjectDisposedException_ReaderClosed(); } var pos = _pos; if ((uint)pos >= (uint)s.Length) @@ -202,7 +203,7 @@ public override string ReadToEnd() { if ((uint)pos < s.Length && s[pos] == '\n') { - ++pos; + pos++; } } _pos = pos; @@ -277,5 +278,12 @@ public override ValueTask ReadAsync(Memory buffer, CancellationToken cancellationToken.IsCancellationRequested ? ValueTask.FromCanceled(cancellationToken) : new ValueTask(Read(buffer.Span)); #endregion + + [DoesNotReturn] + private static void ThrowObjectDisposedException_ReaderClosed() + { + throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); + } + } } diff --git a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs index a5afac1d729aea..e5f4e144dd4611 100644 --- a/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs +++ b/src/libraries/System.Private.CoreLib/src/System/ThrowHelper.cs @@ -392,12 +392,6 @@ internal static void ThrowObjectDisposedException_FileClosed() throw new ObjectDisposedException(null, SR.ObjectDisposed_FileClosed); } - [DoesNotReturn] - internal static void ThrowObjectDisposedException_ReaderClosed() - { - throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); - } - [DoesNotReturn] internal static void ThrowObjectDisposedException(ExceptionResource resource) { From 8bd7254d6e0bce061ad2f8e26e66f690aea04908 Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 28 Nov 2021 11:55:45 +0100 Subject: [PATCH 08/16] remove empty line --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index c051d8a420eed3..ce78a86d56fd55 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -284,6 +284,5 @@ private static void ThrowObjectDisposedException_ReaderClosed() { throw new ObjectDisposedException(null, SR.ObjectDisposed_ReaderClosed); } - } } From 9cf69bf7095d6cc53acb196be14fee1e1f16310b Mon Sep 17 00:00:00 2001 From: ntr Date: Sun, 5 Dec 2021 11:21:41 +0100 Subject: [PATCH 09/16] revert back to Substring --- .../src/System/IO/StringReader.cs | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index ce78a86d56fd55..96148ee8bb0c93 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -193,9 +193,7 @@ public override string ReadToEnd() int foundLineLength = remaining.IndexOfAny('\r', '\n'); if (foundLineLength >= 0) { - string result = foundLineLength == 0 - ? string.Empty - : new string(remaining.Slice(0, foundLineLength)); + string result = s.Substring(pos, foundLineLength); char ch = remaining[foundLineLength]; pos += foundLineLength + 1; @@ -207,17 +205,12 @@ public override string ReadToEnd() } } _pos = pos; + return result; } - else if (remaining.Length == s.Length) - { - // Return source string if only one line avoiding allocation - _pos = s.Length; - return s; - } else { - string result = new string(remaining); + string result = s.Substring(pos); _pos = s.Length; return result; } From 5fcc9643c925a84408e0c9e77e686a65a6857822 Mon Sep 17 00:00:00 2001 From: Adam Sitnik Date: Tue, 7 Dec 2021 17:46:44 +0100 Subject: [PATCH 10/16] Apply suggestions from code review --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 96148ee8bb0c93..8ff42eb62b211d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -185,7 +185,7 @@ public override string ReadToEnd() { ThrowObjectDisposedException_ReaderClosed(); } - var pos = _pos; + int pos = _pos; if ((uint)pos >= (uint)s.Length) return null; From 55aa9069a6a164d2efa57bc0b42776e3bfb3d4b5 Mon Sep 17 00:00:00 2001 From: nietras Date: Tue, 7 Dec 2021 23:01:22 +0100 Subject: [PATCH 11/16] (uint)length Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 8ff42eb62b211d..630a26210b349a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -49,7 +49,7 @@ public override int Peek() } int pos = _pos; - if ((uint)pos < s.Length) + if ((uint)pos < (uint)s.Length) { return s[pos]; } From 8b4eadf39422ef8b71ec9146ef299549ee0e0e03 Mon Sep 17 00:00:00 2001 From: nietras Date: Tue, 7 Dec 2021 23:02:02 +0100 Subject: [PATCH 12/16] (uint)length Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 630a26210b349a..e98ed5ac715090 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -69,7 +69,7 @@ public override int Read() } int pos = _pos; - if ((uint)pos < s.Length) + if ((uint)pos < (uint)s.Length) { _pos++; return s[pos]; From 285165879dcf67bcb937d8092732d2f174fe0cb5 Mon Sep 17 00:00:00 2001 From: nietras Date: Tue, 7 Dec 2021 23:03:39 +0100 Subject: [PATCH 13/16] braces Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index e98ed5ac715090..da98eb16088cc3 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -187,7 +187,9 @@ public override string ReadToEnd() } int pos = _pos; if ((uint)pos >= (uint)s.Length) + { return null; + } ReadOnlySpan remaining = s.AsSpan(pos); int foundLineLength = remaining.IndexOfAny('\r', '\n'); From 01dcca825bb41abf808966bc5c0d764053f6fa87 Mon Sep 17 00:00:00 2001 From: nietras Date: Tue, 7 Dec 2021 23:04:02 +0100 Subject: [PATCH 14/16] empty line Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index da98eb16088cc3..75f95ddaf112cc 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -185,6 +185,7 @@ public override string ReadToEnd() { ThrowObjectDisposedException_ReaderClosed(); } + int pos = _pos; if ((uint)pos >= (uint)s.Length) { From d1551f3f09e2e2218f9e50e59afad39e5bad406d Mon Sep 17 00:00:00 2001 From: nietras Date: Tue, 7 Dec 2021 23:04:32 +0100 Subject: [PATCH 15/16] (uint)length Co-authored-by: Stephen Toub --- .../System.Private.CoreLib/src/System/IO/StringReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index 75f95ddaf112cc..bdbeb50691d453 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -202,7 +202,7 @@ public override string ReadToEnd() pos += foundLineLength + 1; if (ch == '\r') { - if ((uint)pos < s.Length && s[pos] == '\n') + if ((uint)pos < (uint)s.Length && s[pos] == '\n') { pos++; } From 2b85f51ba255dfa2124d91380f5c7ca61f915bba Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 7 Dec 2021 23:14:32 +0100 Subject: [PATCH 16/16] address s local nits --- .../src/System/IO/StringReader.cs | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs index bdbeb50691d453..3d50897ec7f386 100644 --- a/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs +++ b/src/libraries/System.Private.CoreLib/src/System/IO/StringReader.cs @@ -129,12 +129,13 @@ public override int Read(Span buffer) return base.Read(buffer); } - if (_s == null) + string? s = _s; + if (s == null) { ThrowObjectDisposedException_ReaderClosed(); } - int n = _s.Length - _pos; + int n = s.Length - _pos; if (n > 0) { if (n > buffer.Length) @@ -142,7 +143,7 @@ public override int Read(Span buffer) n = buffer.Length; } - _s.AsSpan(_pos, n).CopyTo(buffer); + s.AsSpan(_pos, n).CopyTo(buffer); _pos += n; } @@ -153,22 +154,20 @@ public override int Read(Span buffer) public override string ReadToEnd() { - if (_s == null) + string? s = _s; + if (s == null) { ThrowObjectDisposedException_ReaderClosed(); } - string s; - if (_pos == 0) - { - s = _s; - } - else + int pos = _pos; + _pos = s.Length; + + if (pos != 0) { - s = _s.Substring(_pos); + s = s.Substring(pos); } - _pos = _s.Length; return s; }