diff options
Diffstat (limited to 'src/mscorlib/src/System/IO/StreamReader.cs')
-rw-r--r-- | src/mscorlib/src/System/IO/StreamReader.cs | 249 |
1 files changed, 90 insertions, 159 deletions
diff --git a/src/mscorlib/src/System/IO/StreamReader.cs b/src/mscorlib/src/System/IO/StreamReader.cs index 6d50347b1a..dfb928c85d 100644 --- a/src/mscorlib/src/System/IO/StreamReader.cs +++ b/src/mscorlib/src/System/IO/StreamReader.cs @@ -103,7 +103,7 @@ namespace System.IO Task t = _asyncReadTask; if (t != null && !t.IsCompleted) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncIOInProgress")); + throw new InvalidOperationException(SR.InvalidOperation_AsyncIOInProgress); } // StreamReader by default will ignore illegal UTF8 characters. We don't want to @@ -149,9 +149,9 @@ namespace System.IO if (stream == null || encoding == null) throw new ArgumentNullException((stream == null ? nameof(stream) : nameof(encoding))); if (!stream.CanRead) - throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable")); + throw new ArgumentException(SR.Argument_StreamNotReadable); if (bufferSize <= 0) - throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); + throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum); Contract.EndContractBlock(); Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen); @@ -181,9 +181,9 @@ namespace System.IO if (path==null || encoding==null) throw new ArgumentNullException((path==null ? nameof(path) : nameof(encoding))); if (path.Length==0) - throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath")); + throw new ArgumentException(SR.Argument_EmptyPath); if (bufferSize <= 0) - throw new ArgumentOutOfRangeException(nameof(bufferSize), Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum")); + throw new ArgumentOutOfRangeException(nameof(bufferSize), SR.ArgumentOutOfRange_NeedPosNum); Contract.EndContractBlock(); Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, DefaultFileStreamBufferSize, FileOptions.SequentialScan); @@ -338,11 +338,11 @@ namespace System.IO public override int Read([In, Out] char[] buffer, int index, int count) { if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); + throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + throw new ArgumentException(SR.Argument_InvalidOffLen); Contract.EndContractBlock(); if (stream == null) @@ -396,11 +396,11 @@ namespace System.IO public override int ReadBlock([In, Out] char[] buffer, int index, int count) { if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); + throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + throw new ArgumentException(SR.Argument_InvalidOffLen); Contract.EndContractBlock(); if (stream == null) @@ -540,7 +540,7 @@ namespace System.IO return sb.ToString(); } - internal virtual int ReadBuffer() { + internal int ReadBuffer() { charLen = 0; charPos = 0; @@ -777,16 +777,16 @@ namespace System.IO private async Task<String> ReadLineAsyncInternal() { - if (CharPos_Prop == CharLen_Prop && (await ReadBufferAsync().ConfigureAwait(false)) == 0) + if (charPos == charLen && (await ReadBufferAsync().ConfigureAwait(false)) == 0) return null; StringBuilder sb = null; do { - char[] tmpCharBuffer = CharBuffer_Prop; - int tmpCharLen = CharLen_Prop; - int tmpCharPos = CharPos_Prop; + char[] tmpCharBuffer = charBuffer; + int tmpCharLen = charLen; + int tmpCharPos = charPos; int i = tmpCharPos; do @@ -809,13 +809,13 @@ namespace System.IO s = new String(tmpCharBuffer, tmpCharPos, i - tmpCharPos); } - CharPos_Prop = tmpCharPos = i + 1; + charPos = tmpCharPos = i + 1; if (ch == '\r' && (tmpCharPos < tmpCharLen || (await ReadBufferAsync().ConfigureAwait(false)) > 0)) { - tmpCharPos = CharPos_Prop; - if (CharBuffer_Prop[tmpCharPos] == '\n') - CharPos_Prop = ++tmpCharPos; + tmpCharPos = charPos; + if (charBuffer[tmpCharPos] == '\n') + charPos = ++tmpCharPos; } return s; @@ -857,14 +857,14 @@ namespace System.IO private async Task<String> ReadToEndAsyncInternal() { // Call ReadBuffer, then pull data out of charBuffer. - StringBuilder sb = AcquireSharedStringBuilder(CharLen_Prop - CharPos_Prop); + StringBuilder sb = AcquireSharedStringBuilder(charLen - charPos); do { - int tmpCharPos = CharPos_Prop; - sb.Append(CharBuffer_Prop, tmpCharPos, CharLen_Prop - tmpCharPos); - CharPos_Prop = CharLen_Prop; // We consumed these characters + int tmpCharPos = charPos; + sb.Append(charBuffer, tmpCharPos, charLen - tmpCharPos); + charPos = charLen; // We consumed these characters await ReadBufferAsync().ConfigureAwait(false); - } while (CharLen_Prop > 0); + } while (charLen > 0); return GetStringAndReleaseSharedStringBuilder(sb); } @@ -872,11 +872,11 @@ namespace System.IO public override Task<int> ReadAsync(char[] buffer, int index, int count) { if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); + throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + throw new ArgumentException(SR.Argument_InvalidOffLen); Contract.EndContractBlock(); // If we have been inherited into a subclass, the following implementation could be incorrect @@ -899,7 +899,7 @@ namespace System.IO internal override async Task<int> ReadAsyncInternal(char[] buffer, int index, int count) { - if (CharPos_Prop == CharLen_Prop && (await ReadBufferAsync().ConfigureAwait(false)) == 0) + if (charPos == charLen && (await ReadBufferAsync().ConfigureAwait(false)) == 0) return 0; int charsRead = 0; @@ -908,24 +908,24 @@ namespace System.IO // data read in, let's try writing directly to the user's buffer. bool readToUserBuffer = false; - Byte[] tmpByteBuffer = ByteBuffer_Prop; - Stream tmpStream = Stream_Prop; + Byte[] tmpByteBuffer = byteBuffer; + Stream tmpStream = stream; while (count > 0) { // n is the characters available in _charBuffer - int n = CharLen_Prop - CharPos_Prop; + int n = charLen - charPos; // charBuffer is empty, let's read from the stream if (n == 0) { - CharLen_Prop = 0; - CharPos_Prop = 0; + charLen = 0; + charPos = 0; - if (!CheckPreamble_Prop) - ByteLen_Prop = 0; + if (!_checkPreamble) + byteLen = 0; - readToUserBuffer = count >= MaxCharsPerBuffer_Prop; + readToUserBuffer = count >= _maxCharsPerBuffer; // We loop here so that we read in enough bytes to yield at least 1 char. // We break out of the loop if the stream is blocked (EOF is reached). @@ -933,10 +933,10 @@ namespace System.IO { Debug.Assert(n == 0); - if (CheckPreamble_Prop) + if (_checkPreamble) { - Debug.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?"); - int tmpBytePos = BytePos_Prop; + Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?"); + int tmpBytePos = bytePos; int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false); Debug.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class."); @@ -944,42 +944,42 @@ namespace System.IO { // EOF but we might have buffered bytes from previous // attempts to detect preamble that needs to be decoded now - if (ByteLen_Prop > 0) + if (byteLen > 0) { if (readToUserBuffer) { - n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead); - CharLen_Prop = 0; // StreamReader's buffer is empty. + n = decoder.GetChars(tmpByteBuffer, 0, byteLen, buffer, index + charsRead); + charLen = 0; // StreamReader's buffer is empty. } else { - n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0); - CharLen_Prop += n; // Number of chars in StreamReader's buffer. + n = decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, 0); + charLen += n; // Number of chars in StreamReader's buffer. } } // How can part of the preamble yield any chars? Debug.Assert(n == 0); - IsBlocked_Prop = true; + _isBlocked = true; break; } else { - ByteLen_Prop += len; + byteLen += len; } } else { - Debug.Assert(BytePos_Prop == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?"); + Debug.Assert(bytePos == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?"); - ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false); + byteLen = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false); - Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! This is a bug in your stream class."); + Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number! This is a bug in your stream class."); - if (ByteLen_Prop == 0) // EOF + if (byteLen == 0) // EOF { - IsBlocked_Prop = true; + _isBlocked = true; break; } } @@ -987,7 +987,7 @@ namespace System.IO // _isBlocked == whether we read fewer bytes than we asked for. // Note we must check it here because CompressBuffer or // DetectEncoding will change _byteLen. - IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length); + _isBlocked = (byteLen < tmpByteBuffer.Length); // Check for preamble before detect encoding. This is not to override the // user suppplied Encoding for the one we implicitly detect. The user could @@ -998,33 +998,33 @@ namespace System.IO continue; // On the first call to ReadBuffer, if we're supposed to detect the encoding, do it. - if (DetectEncoding_Prop && ByteLen_Prop >= 2) + if (_detectEncoding && byteLen >= 2) { DetectEncoding(); // DetectEncoding changes some buffer state. Recompute this. - readToUserBuffer = count >= MaxCharsPerBuffer_Prop; + readToUserBuffer = count >= _maxCharsPerBuffer; } Debug.Assert(n == 0); - CharPos_Prop = 0; + charPos = 0; if (readToUserBuffer) { - n += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead); + n += decoder.GetChars(tmpByteBuffer, 0, byteLen, buffer, index + charsRead); // Why did the bytes yield no chars? Debug.Assert(n > 0); - CharLen_Prop = 0; // StreamReader's buffer is empty. + charLen = 0; // StreamReader's buffer is empty. } else { - n = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0); + n = decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, 0); // Why did the bytes yield no chars? Debug.Assert(n > 0); - CharLen_Prop += n; // Number of chars in StreamReader's buffer. + charLen += n; // Number of chars in StreamReader's buffer. } } while (n == 0); @@ -1038,8 +1038,8 @@ namespace System.IO if (!readToUserBuffer) { - Buffer.InternalBlockCopy(CharBuffer_Prop, CharPos_Prop * 2, buffer, (index + charsRead) * 2, n * 2); - CharPos_Prop += n; + Buffer.InternalBlockCopy(charBuffer, charPos * 2, buffer, (index + charsRead) * 2, n * 2); + charPos += n; } charsRead += n; @@ -1048,7 +1048,7 @@ namespace System.IO // This function shouldn't block for an indefinite amount of time, // or reading from a network stream won't work right. If we got // fewer bytes than we requested, then we want to break right here. - if (IsBlocked_Prop) + if (_isBlocked) break; } // while (count > 0) @@ -1058,11 +1058,11 @@ namespace System.IO public override Task<int> ReadBlockAsync(char[] buffer, int index, int count) { if (buffer==null) - throw new ArgumentNullException(nameof(buffer), Environment.GetResourceString("ArgumentNull_Buffer")); + throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); if (index < 0 || count < 0) - throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum); if (buffer.Length - index < count) - throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen")); + throw new ArgumentException(SR.Argument_InvalidOffLen); Contract.EndContractBlock(); // If we have been inherited into a subclass, the following implementation could be incorrect @@ -1083,113 +1083,50 @@ namespace System.IO return task; } - #region Private properties for async method performance - // Access to instance fields of MarshalByRefObject-derived types requires special JIT helpers that check - // if the instance operated on is remote. This is optimised for fields on this but if a method is Async - // and is thus lifted to a state machine type, access will be slow. - // As a workaround, we either cache instance fields in locals or use properties to access such fields. - - private Int32 CharLen_Prop { - get { return charLen; } - set { charLen = value; } - } - - private Int32 CharPos_Prop { - get { return charPos; } - set { charPos = value; } - } - - private Int32 ByteLen_Prop { - get { return byteLen; } - set { byteLen = value; } - } - - private Int32 BytePos_Prop { - get { return bytePos; } - set { bytePos = value; } - } - - private Byte[] Preamble_Prop { - get { return _preamble; } - } - - private bool CheckPreamble_Prop { - get { return _checkPreamble; } - } - - private Decoder Decoder_Prop { - get { return decoder; } - } - - private bool DetectEncoding_Prop { - get { return _detectEncoding; } - } - - private Char[] CharBuffer_Prop { - get { return charBuffer; } - } - - private Byte[] ByteBuffer_Prop { - get { return byteBuffer; } - } - - private bool IsBlocked_Prop { - get { return _isBlocked; } - set { _isBlocked = value; } - } - - private Stream Stream_Prop { - get { return stream; } - } - - private Int32 MaxCharsPerBuffer_Prop { - get { return _maxCharsPerBuffer; } - } - #endregion Private properties for async method performance private async Task<int> ReadBufferAsync() { - CharLen_Prop = 0; - CharPos_Prop = 0; - Byte[] tmpByteBuffer = ByteBuffer_Prop; - Stream tmpStream = Stream_Prop; + charLen = 0; + charPos = 0; + Byte[] tmpByteBuffer = byteBuffer; + Stream tmpStream = stream; - if (!CheckPreamble_Prop) - ByteLen_Prop = 0; + if (!_checkPreamble) + byteLen = 0; do { - if (CheckPreamble_Prop) { - Debug.Assert(BytePos_Prop <= Preamble_Prop.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?"); - int tmpBytePos = BytePos_Prop; + if (_checkPreamble) { + Debug.Assert(bytePos <= _preamble.Length, "possible bug in _compressPreamble. Are two threads using this StreamReader at the same time?"); + int tmpBytePos = bytePos; int len = await tmpStream.ReadAsync(tmpByteBuffer, tmpBytePos, tmpByteBuffer.Length - tmpBytePos).ConfigureAwait(false); Debug.Assert(len >= 0, "Stream.Read returned a negative number! This is a bug in your stream class."); if (len == 0) { // EOF but we might have buffered bytes from previous // attempt to detect preamble that needs to be decoded now - if (ByteLen_Prop > 0) + if (byteLen > 0) { - CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop); + charLen += decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, charLen); // Need to zero out the _byteLen after we consume these bytes so that we don't keep infinitely hitting this code path - BytePos_Prop = 0; ByteLen_Prop = 0; + bytePos = 0; byteLen = 0; } - return CharLen_Prop; + return charLen; } - ByteLen_Prop += len; + byteLen += len; } else { - Debug.Assert(BytePos_Prop == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?"); - ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false); - Debug.Assert(ByteLen_Prop >= 0, "Stream.Read returned a negative number! Bug in stream class."); + Debug.Assert(bytePos == 0, "_bytePos can be non zero only when we are trying to _checkPreamble. Are two threads using this StreamReader at the same time?"); + byteLen = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(false); + Debug.Assert(byteLen >= 0, "Stream.Read returned a negative number! Bug in stream class."); - if (ByteLen_Prop == 0) // We're at EOF - return CharLen_Prop; + if (byteLen == 0) // We're at EOF + return charLen; } // _isBlocked == whether we read fewer bytes than we asked for. // Note we must check it here because CompressBuffer or // DetectEncoding will change _byteLen. - IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length); + _isBlocked = (byteLen < tmpByteBuffer.Length); // Check for preamble before detect encoding. This is not to override the // user suppplied Encoding for the one we implicitly detect. The user could @@ -1199,13 +1136,13 @@ namespace System.IO // If we're supposed to detect the encoding and haven't done so yet, // do it. Note this may need to be called more than once. - if (DetectEncoding_Prop && ByteLen_Prop >= 2) + if (_detectEncoding && byteLen >= 2) DetectEncoding(); - CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop); - } while (CharLen_Prop == 0); + charLen += decoder.GetChars(tmpByteBuffer, 0, byteLen, charBuffer, charLen); + } while (charLen == 0); - return CharLen_Prop; + return charLen; } #endregion @@ -1254,12 +1191,6 @@ namespace System.IO { return String.Empty; } - - internal override int ReadBuffer() - { - return 0; - } - } } } |