mscorlib(4.0.0.0) API with additions
StreamReader.cs
2 using System.Security;
4 using System.Text;
6 
7 namespace System.IO
8 {
10  [Serializable]
11  [ComVisible(true)]
12  [__DynamicallyInvokable]
13  public class StreamReader : TextReader
14  {
15  private class NullStreamReader : StreamReader
16  {
17  public override Stream BaseStream => Stream.Null;
18 
19  public override Encoding CurrentEncoding => Encoding.Unicode;
20 
21  internal NullStreamReader()
22  {
23  Init(Stream.Null);
24  }
25 
26  protected override void Dispose(bool disposing)
27  {
28  }
29 
30  public override int Peek()
31  {
32  return -1;
33  }
34 
35  public override int Read()
36  {
37  return -1;
38  }
39 
40  public override int Read(char[] buffer, int index, int count)
41  {
42  return 0;
43  }
44 
45  public override string ReadLine()
46  {
47  return null;
48  }
49 
50  public override string ReadToEnd()
51  {
52  return string.Empty;
53  }
54 
55  internal override int ReadBuffer()
56  {
57  return 0;
58  }
59  }
60 
62  [__DynamicallyInvokable]
63  public new static readonly StreamReader Null = new NullStreamReader();
64 
65  private const int DefaultFileStreamBufferSize = 4096;
66 
67  private const int MinBufferSize = 128;
68 
69  private Stream stream;
70 
71  private Encoding encoding;
72 
73  private Decoder decoder;
74 
75  private byte[] byteBuffer;
76 
77  private char[] charBuffer;
78 
79  private byte[] _preamble;
80 
81  private int charPos;
82 
83  private int charLen;
84 
85  private int byteLen;
86 
87  private int bytePos;
88 
89  private int _maxCharsPerBuffer;
90 
91  private bool _detectEncoding;
92 
93  private bool _checkPreamble;
94 
95  private bool _isBlocked;
96 
97  private bool _closable;
98 
99  [NonSerialized]
100  private volatile Task _asyncReadTask;
101 
102  internal static int DefaultBufferSize => 1024;
103 
106  [__DynamicallyInvokable]
107  public virtual Encoding CurrentEncoding
108  {
109  [__DynamicallyInvokable]
110  get
111  {
112  return encoding;
113  }
114  }
115 
118  [__DynamicallyInvokable]
119  public virtual Stream BaseStream
120  {
121  [__DynamicallyInvokable]
122  get
123  {
124  return stream;
125  }
126  }
127 
128  internal bool LeaveOpen => !_closable;
129 
134  [__DynamicallyInvokable]
135  public bool EndOfStream
136  {
137  [__DynamicallyInvokable]
138  get
139  {
140  if (stream == null)
141  {
142  __Error.ReaderClosed();
143  }
144  CheckAsyncTaskInProgress();
145  if (charPos < charLen)
146  {
147  return false;
148  }
149  int num = ReadBuffer();
150  return num == 0;
151  }
152  }
153 
154  private int CharLen_Prop
155  {
156  get
157  {
158  return charLen;
159  }
160  set
161  {
162  charLen = value;
163  }
164  }
165 
166  private int CharPos_Prop
167  {
168  get
169  {
170  return charPos;
171  }
172  set
173  {
174  charPos = value;
175  }
176  }
177 
178  private int ByteLen_Prop
179  {
180  get
181  {
182  return byteLen;
183  }
184  set
185  {
186  byteLen = value;
187  }
188  }
189 
190  private int BytePos_Prop
191  {
192  get
193  {
194  return bytePos;
195  }
196  set
197  {
198  bytePos = value;
199  }
200  }
201 
202  private byte[] Preamble_Prop => _preamble;
203 
204  private bool CheckPreamble_Prop => _checkPreamble;
205 
206  private Decoder Decoder_Prop => decoder;
207 
208  private bool DetectEncoding_Prop => _detectEncoding;
209 
210  private char[] CharBuffer_Prop => charBuffer;
211 
212  private byte[] ByteBuffer_Prop => byteBuffer;
213 
214  private bool IsBlocked_Prop
215  {
216  get
217  {
218  return _isBlocked;
219  }
220  set
221  {
222  _isBlocked = value;
223  }
224  }
225 
226  private Stream Stream_Prop => stream;
227 
228  private int MaxCharsPerBuffer_Prop => _maxCharsPerBuffer;
229 
230  private void CheckAsyncTaskInProgress()
231  {
232  Task asyncReadTask = _asyncReadTask;
233  if (asyncReadTask != null && !asyncReadTask.IsCompleted)
234  {
235  throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_AsyncIOInProgress"));
236  }
237  }
238 
239  internal StreamReader()
240  {
241  }
242 
249  [__DynamicallyInvokable]
250  public StreamReader(Stream stream)
251  : this(stream, detectEncodingFromByteOrderMarks: true)
252  {
253  }
254 
262  [__DynamicallyInvokable]
263  public StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
264  : this(stream, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize, leaveOpen: false)
265  {
266  }
267 
275  [__DynamicallyInvokable]
276  public StreamReader(Stream stream, Encoding encoding)
277  : this(stream, encoding, detectEncodingFromByteOrderMarks: true, DefaultBufferSize, leaveOpen: false)
278  {
279  }
280 
289  [__DynamicallyInvokable]
290  public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)
291  : this(stream, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize, leaveOpen: false)
292  {
293  }
294 
305  [__DynamicallyInvokable]
306  public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
307  : this(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen: false)
308  {
309  }
310 
319  [__DynamicallyInvokable]
320  public StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
321  {
322  if (stream == null || encoding == null)
323  {
324  throw new ArgumentNullException((stream == null) ? "stream" : "encoding");
325  }
326  if (!stream.CanRead)
327  {
328  throw new ArgumentException(Environment.GetResourceString("Argument_StreamNotReadable"));
329  }
330  if (bufferSize <= 0)
331  {
332  throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
333  }
334  Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen);
335  }
336 
347  public StreamReader(string path)
348  : this(path, detectEncodingFromByteOrderMarks: true)
349  {
350  }
351 
363  public StreamReader(string path, bool detectEncodingFromByteOrderMarks)
364  : this(path, Encoding.UTF8, detectEncodingFromByteOrderMarks, DefaultBufferSize)
365  {
366  }
367 
379  public StreamReader(string path, Encoding encoding)
380  : this(path, encoding, detectEncodingFromByteOrderMarks: true, DefaultBufferSize)
381  {
382  }
383 
396  public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)
397  : this(path, encoding, detectEncodingFromByteOrderMarks, DefaultBufferSize)
398  {
399  }
400 
416  [SecuritySafeCritical]
417  public StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
418  : this(path, encoding, detectEncodingFromByteOrderMarks, bufferSize, checkHost: true)
419  {
420  }
421 
422  [SecurityCritical]
423  internal StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool checkHost)
424  {
425  if (path == null || encoding == null)
426  {
427  throw new ArgumentNullException((path == null) ? "path" : "encoding");
428  }
429  if (path.Length == 0)
430  {
431  throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
432  }
433  if (bufferSize <= 0)
434  {
435  throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
436  }
437  Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, FileOptions.SequentialScan, Path.GetFileName(path), bFromProxy: false, useLongPath: false, checkHost);
438  Init(stream, encoding, detectEncodingFromByteOrderMarks, bufferSize, leaveOpen: false);
439  }
440 
441  private void Init(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
442  {
443  this.stream = stream;
444  this.encoding = encoding;
445  decoder = encoding.GetDecoder();
446  if (bufferSize < 128)
447  {
448  bufferSize = 128;
449  }
450  byteBuffer = new byte[bufferSize];
451  _maxCharsPerBuffer = encoding.GetMaxCharCount(bufferSize);
452  charBuffer = new char[_maxCharsPerBuffer];
453  byteLen = 0;
454  bytePos = 0;
455  _detectEncoding = detectEncodingFromByteOrderMarks;
456  _preamble = encoding.GetPreamble();
457  _checkPreamble = (_preamble.Length != 0);
458  _isBlocked = false;
459  _closable = !leaveOpen;
460  }
461 
462  internal void Init(Stream stream)
463  {
464  this.stream = stream;
465  _closable = true;
466  }
467 
469  public override void Close()
470  {
471  Dispose(disposing: true);
472  }
473 
477  [__DynamicallyInvokable]
478  protected override void Dispose(bool disposing)
479  {
480  try
481  {
482  if (!LeaveOpen && disposing && stream != null)
483  {
484  stream.Close();
485  }
486  }
487  finally
488  {
489  if (!LeaveOpen && stream != null)
490  {
491  stream = null;
492  encoding = null;
493  decoder = null;
494  byteBuffer = null;
495  charBuffer = null;
496  charPos = 0;
497  charLen = 0;
498  base.Dispose(disposing);
499  }
500  }
501  }
502 
504  [__DynamicallyInvokable]
505  public void DiscardBufferedData()
506  {
507  CheckAsyncTaskInProgress();
508  byteLen = 0;
509  charLen = 0;
510  charPos = 0;
511  if (encoding != null)
512  {
513  decoder = encoding.GetDecoder();
514  }
515  _isBlocked = false;
516  }
517 
521  [__DynamicallyInvokable]
522  public override int Peek()
523  {
524  if (stream == null)
525  {
526  __Error.ReaderClosed();
527  }
528  CheckAsyncTaskInProgress();
529  if (charPos == charLen && (_isBlocked || ReadBuffer() == 0))
530  {
531  return -1;
532  }
533  return charBuffer[charPos];
534  }
535 
539  [__DynamicallyInvokable]
540  public override int Read()
541  {
542  if (stream == null)
543  {
544  __Error.ReaderClosed();
545  }
546  CheckAsyncTaskInProgress();
547  if (charPos == charLen && ReadBuffer() == 0)
548  {
549  return -1;
550  }
551  int result = charBuffer[charPos];
552  charPos++;
553  return result;
554  }
555 
567  [__DynamicallyInvokable]
568  public override int Read([In] [Out] char[] buffer, int index, int count)
569  {
570  if (buffer == null)
571  {
572  throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
573  }
574  if (index < 0 || count < 0)
575  {
576  throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
577  }
578  if (buffer.Length - index < count)
579  {
580  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
581  }
582  if (stream == null)
583  {
584  __Error.ReaderClosed();
585  }
586  CheckAsyncTaskInProgress();
587  int num = 0;
588  bool readToUserBuffer = false;
589  while (count > 0)
590  {
591  int num2 = charLen - charPos;
592  if (num2 == 0)
593  {
594  num2 = ReadBuffer(buffer, index + num, count, out readToUserBuffer);
595  }
596  if (num2 == 0)
597  {
598  break;
599  }
600  if (num2 > count)
601  {
602  num2 = count;
603  }
604  if (!readToUserBuffer)
605  {
606  Buffer.InternalBlockCopy(charBuffer, charPos * 2, buffer, (index + num) * 2, num2 * 2);
607  charPos += num2;
608  }
609  num += num2;
610  count -= num2;
611  if (_isBlocked)
612  {
613  break;
614  }
615  }
616  return num;
617  }
618 
623  [__DynamicallyInvokable]
624  public override string ReadToEnd()
625  {
626  if (stream == null)
627  {
628  __Error.ReaderClosed();
629  }
630  CheckAsyncTaskInProgress();
631  StringBuilder stringBuilder = new StringBuilder(charLen - charPos);
632  do
633  {
634  stringBuilder.Append(charBuffer, charPos, charLen - charPos);
635  charPos = charLen;
636  ReadBuffer();
637  }
638  while (charLen > 0);
639  return stringBuilder.ToString();
640  }
641 
654  [__DynamicallyInvokable]
655  public override int ReadBlock([In] [Out] char[] buffer, int index, int count)
656  {
657  if (buffer == null)
658  {
659  throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
660  }
661  if (index < 0 || count < 0)
662  {
663  throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
664  }
665  if (buffer.Length - index < count)
666  {
667  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
668  }
669  if (stream == null)
670  {
671  __Error.ReaderClosed();
672  }
673  CheckAsyncTaskInProgress();
674  return base.ReadBlock(buffer, index, count);
675  }
676 
677  private void CompressBuffer(int n)
678  {
679  Buffer.InternalBlockCopy(byteBuffer, n, byteBuffer, 0, byteLen - n);
680  byteLen -= n;
681  }
682 
683  private void DetectEncoding()
684  {
685  if (byteLen < 2)
686  {
687  return;
688  }
689  _detectEncoding = false;
690  bool flag = false;
691  if (byteBuffer[0] == 254 && byteBuffer[1] == byte.MaxValue)
692  {
693  encoding = new UnicodeEncoding(bigEndian: true, byteOrderMark: true);
694  CompressBuffer(2);
695  flag = true;
696  }
697  else if (byteBuffer[0] == byte.MaxValue && byteBuffer[1] == 254)
698  {
699  if (byteLen < 4 || byteBuffer[2] != 0 || byteBuffer[3] != 0)
700  {
701  encoding = new UnicodeEncoding(bigEndian: false, byteOrderMark: true);
702  CompressBuffer(2);
703  flag = true;
704  }
705  else
706  {
707  encoding = new UTF32Encoding(bigEndian: false, byteOrderMark: true);
708  CompressBuffer(4);
709  flag = true;
710  }
711  }
712  else if (byteLen >= 3 && byteBuffer[0] == 239 && byteBuffer[1] == 187 && byteBuffer[2] == 191)
713  {
714  encoding = Encoding.UTF8;
715  CompressBuffer(3);
716  flag = true;
717  }
718  else if (byteLen >= 4 && byteBuffer[0] == 0 && byteBuffer[1] == 0 && byteBuffer[2] == 254 && byteBuffer[3] == byte.MaxValue)
719  {
720  encoding = new UTF32Encoding(bigEndian: true, byteOrderMark: true);
721  CompressBuffer(4);
722  flag = true;
723  }
724  else if (byteLen == 2)
725  {
726  _detectEncoding = true;
727  }
728  if (flag)
729  {
730  decoder = encoding.GetDecoder();
731  _maxCharsPerBuffer = encoding.GetMaxCharCount(byteBuffer.Length);
732  charBuffer = new char[_maxCharsPerBuffer];
733  }
734  }
735 
736  private bool IsPreamble()
737  {
738  if (!_checkPreamble)
739  {
740  return _checkPreamble;
741  }
742  int num = (byteLen >= _preamble.Length) ? (_preamble.Length - bytePos) : (byteLen - bytePos);
743  int num2 = 0;
744  while (num2 < num)
745  {
746  if (byteBuffer[bytePos] != _preamble[bytePos])
747  {
748  bytePos = 0;
749  _checkPreamble = false;
750  break;
751  }
752  num2++;
753  bytePos++;
754  }
755  if (_checkPreamble && bytePos == _preamble.Length)
756  {
757  CompressBuffer(_preamble.Length);
758  bytePos = 0;
759  _checkPreamble = false;
760  _detectEncoding = false;
761  }
762  return _checkPreamble;
763  }
764 
765  internal virtual int ReadBuffer()
766  {
767  charLen = 0;
768  charPos = 0;
769  if (!_checkPreamble)
770  {
771  byteLen = 0;
772  }
773  do
774  {
775  if (_checkPreamble)
776  {
777  int num = stream.Read(byteBuffer, bytePos, byteBuffer.Length - bytePos);
778  if (num == 0)
779  {
780  if (byteLen > 0)
781  {
782  charLen += decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen);
783  bytePos = (byteLen = 0);
784  }
785  return charLen;
786  }
787  byteLen += num;
788  }
789  else
790  {
791  byteLen = stream.Read(byteBuffer, 0, byteBuffer.Length);
792  if (byteLen == 0)
793  {
794  return charLen;
795  }
796  }
797  _isBlocked = (byteLen < byteBuffer.Length);
798  if (!IsPreamble())
799  {
800  if (_detectEncoding && byteLen >= 2)
801  {
802  DetectEncoding();
803  }
804  charLen += decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, charLen);
805  }
806  }
807  while (charLen == 0);
808  return charLen;
809  }
810 
811  private int ReadBuffer(char[] userBuffer, int userOffset, int desiredChars, out bool readToUserBuffer)
812  {
813  charLen = 0;
814  charPos = 0;
815  if (!_checkPreamble)
816  {
817  byteLen = 0;
818  }
819  int num = 0;
820  readToUserBuffer = (desiredChars >= _maxCharsPerBuffer);
821  do
822  {
823  if (_checkPreamble)
824  {
825  int num2 = stream.Read(byteBuffer, bytePos, byteBuffer.Length - bytePos);
826  if (num2 == 0)
827  {
828  if (byteLen > 0)
829  {
830  if (readToUserBuffer)
831  {
832  num = decoder.GetChars(byteBuffer, 0, byteLen, userBuffer, userOffset + num);
833  charLen = 0;
834  }
835  else
836  {
837  num = decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, num);
838  charLen += num;
839  }
840  }
841  return num;
842  }
843  byteLen += num2;
844  }
845  else
846  {
847  byteLen = stream.Read(byteBuffer, 0, byteBuffer.Length);
848  if (byteLen == 0)
849  {
850  break;
851  }
852  }
853  _isBlocked = (byteLen < byteBuffer.Length);
854  if (!IsPreamble())
855  {
856  if (_detectEncoding && byteLen >= 2)
857  {
858  DetectEncoding();
859  readToUserBuffer = (desiredChars >= _maxCharsPerBuffer);
860  }
861  charPos = 0;
862  if (readToUserBuffer)
863  {
864  num += decoder.GetChars(byteBuffer, 0, byteLen, userBuffer, userOffset + num);
865  charLen = 0;
866  }
867  else
868  {
869  num = decoder.GetChars(byteBuffer, 0, byteLen, charBuffer, num);
870  charLen += num;
871  }
872  }
873  }
874  while (num == 0);
875  _isBlocked = (_isBlocked && num < desiredChars);
876  return num;
877  }
878 
883  [__DynamicallyInvokable]
884  public override string ReadLine()
885  {
886  if (stream == null)
887  {
888  __Error.ReaderClosed();
889  }
890  CheckAsyncTaskInProgress();
891  if (charPos == charLen && ReadBuffer() == 0)
892  {
893  return null;
894  }
895  StringBuilder stringBuilder = null;
896  do
897  {
898  int num = charPos;
899  do
900  {
901  char c = charBuffer[num];
902  if (c == '\r' || c == '\n')
903  {
904  string result;
905  if (stringBuilder != null)
906  {
907  stringBuilder.Append(charBuffer, charPos, num - charPos);
908  result = stringBuilder.ToString();
909  }
910  else
911  {
912  result = new string(charBuffer, charPos, num - charPos);
913  }
914  charPos = num + 1;
915  if (c == '\r' && (charPos < charLen || ReadBuffer() > 0) && charBuffer[charPos] == '\n')
916  {
917  charPos++;
918  }
919  return result;
920  }
921  num++;
922  }
923  while (num < charLen);
924  num = charLen - charPos;
925  if (stringBuilder == null)
926  {
927  stringBuilder = new StringBuilder(num + 80);
928  }
929  stringBuilder.Append(charBuffer, charPos, num);
930  }
931  while (ReadBuffer() > 0);
932  return stringBuilder.ToString();
933  }
934 
940  [ComVisible(false)]
941  [__DynamicallyInvokable]
942  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
943  public override Task<string> ReadLineAsync()
944  {
945  if (GetType() != typeof(StreamReader))
946  {
947  return base.ReadLineAsync();
948  }
949  if (stream == null)
950  {
951  __Error.ReaderClosed();
952  }
953  CheckAsyncTaskInProgress();
954  return (Task<string>)(_asyncReadTask = ReadLineAsyncInternal());
955  }
956 
957  private async Task<string> ReadLineAsyncInternal()
958  {
959  bool flag = CharPos_Prop == CharLen_Prop;
960  bool flag2 = flag;
961  if (flag2)
962  {
963  flag2 = (await ReadBufferAsync().ConfigureAwait(continueOnCapturedContext: false) == 0);
964  }
965  if (flag2)
966  {
967  return null;
968  }
969  StringBuilder sb = null;
970  do
971  {
972  char[] tmpCharBuffer = CharBuffer_Prop;
973  int tmpCharLen = CharLen_Prop;
974  int tmpCharPos3 = CharPos_Prop;
975  int j = tmpCharPos3;
976  do
977  {
978  char c = tmpCharBuffer[j];
979  if (c == '\r' || c == '\n')
980  {
981  string s;
982  if (sb != null)
983  {
984  sb.Append(tmpCharBuffer, tmpCharPos3, j - tmpCharPos3);
985  s = sb.ToString();
986  }
987  else
988  {
989  s = new string(tmpCharBuffer, tmpCharPos3, j - tmpCharPos3);
990  }
991  tmpCharPos3 = (CharPos_Prop = j + 1);
992  bool flag3 = c == '\r';
993  if (flag3)
994  {
995  bool flag4 = tmpCharPos3 < tmpCharLen;
996  if (!flag4)
997  {
998  flag4 = (await ReadBufferAsync().ConfigureAwait(continueOnCapturedContext: false) > 0);
999  }
1000  flag3 = flag4;
1001  }
1002  if (flag3)
1003  {
1004  tmpCharPos3 = CharPos_Prop;
1005  if (CharBuffer_Prop[tmpCharPos3] == '\n')
1006  {
1007  CharPos_Prop = tmpCharPos3 + 1;
1008  }
1009  }
1010  return s;
1011  }
1012  j++;
1013  }
1014  while (j < tmpCharLen);
1015  j = tmpCharLen - tmpCharPos3;
1016  if (sb == null)
1017  {
1018  sb = new StringBuilder(j + 80);
1019  }
1020  sb.Append(tmpCharBuffer, tmpCharPos3, j);
1021  }
1022  while (await ReadBufferAsync().ConfigureAwait(continueOnCapturedContext: false) > 0);
1023  return sb.ToString();
1024  }
1025 
1031  [ComVisible(false)]
1032  [__DynamicallyInvokable]
1033  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
1034  public override Task<string> ReadToEndAsync()
1035  {
1036  if (GetType() != typeof(StreamReader))
1037  {
1038  return base.ReadToEndAsync();
1039  }
1040  if (stream == null)
1041  {
1042  __Error.ReaderClosed();
1043  }
1044  CheckAsyncTaskInProgress();
1045  return (Task<string>)(_asyncReadTask = ReadToEndAsyncInternal());
1046  }
1047 
1048  private async Task<string> ReadToEndAsyncInternal()
1049  {
1050  StringBuilder sb = new StringBuilder(CharLen_Prop - CharPos_Prop);
1051  do
1052  {
1053  int charPos_Prop = CharPos_Prop;
1054  sb.Append(CharBuffer_Prop, charPos_Prop, CharLen_Prop - charPos_Prop);
1055  CharPos_Prop = CharLen_Prop;
1056  await ReadBufferAsync().ConfigureAwait(continueOnCapturedContext: false);
1057  }
1058  while (CharLen_Prop > 0);
1059  return sb.ToString();
1060  }
1061 
1074  [ComVisible(false)]
1075  [__DynamicallyInvokable]
1076  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
1077  public override Task<int> ReadAsync(char[] buffer, int index, int count)
1078  {
1079  if (buffer == null)
1080  {
1081  throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
1082  }
1083  if (index < 0 || count < 0)
1084  {
1085  throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1086  }
1087  if (buffer.Length - index < count)
1088  {
1089  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1090  }
1091  if (GetType() != typeof(StreamReader))
1092  {
1093  return base.ReadAsync(buffer, index, count);
1094  }
1095  if (stream == null)
1096  {
1097  __Error.ReaderClosed();
1098  }
1099  CheckAsyncTaskInProgress();
1100  return (Task<int>)(_asyncReadTask = ReadAsyncInternal(buffer, index, count));
1101  }
1102 
1103  internal override async Task<int> ReadAsyncInternal(char[] buffer, int index, int count)
1104  {
1105  bool flag = CharPos_Prop == CharLen_Prop;
1106  bool flag2 = flag;
1107  if (flag2)
1108  {
1109  flag2 = (await ReadBufferAsync().ConfigureAwait(continueOnCapturedContext: false) == 0);
1110  }
1111  if (flag2)
1112  {
1113  return 0;
1114  }
1115  int charsRead = 0;
1116  bool readToUserBuffer = false;
1117  byte[] tmpByteBuffer = ByteBuffer_Prop;
1118  Stream tmpStream = Stream_Prop;
1119  while (count > 0)
1120  {
1121  int i = CharLen_Prop - CharPos_Prop;
1122  if (i == 0)
1123  {
1124  CharLen_Prop = 0;
1125  CharPos_Prop = 0;
1126  if (!CheckPreamble_Prop)
1127  {
1128  ByteLen_Prop = 0;
1129  }
1130  readToUserBuffer = (count >= MaxCharsPerBuffer_Prop);
1131  do
1132  {
1133  if (CheckPreamble_Prop)
1134  {
1135  int bytePos_Prop = BytePos_Prop;
1136  int num = await tmpStream.ReadAsync(tmpByteBuffer, bytePos_Prop, tmpByteBuffer.Length - bytePos_Prop).ConfigureAwait(continueOnCapturedContext: false);
1137  if (num == 0)
1138  {
1139  if (ByteLen_Prop > 0)
1140  {
1141  if (readToUserBuffer)
1142  {
1143  i = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead);
1144  CharLen_Prop = 0;
1145  }
1146  else
1147  {
1148  i = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0);
1149  CharLen_Prop += i;
1150  }
1151  }
1152  IsBlocked_Prop = true;
1153  break;
1154  }
1155  ByteLen_Prop += num;
1156  }
1157  else
1158  {
1159  ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(continueOnCapturedContext: false);
1160  if (ByteLen_Prop == 0)
1161  {
1162  IsBlocked_Prop = true;
1163  break;
1164  }
1165  }
1166  IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length);
1167  if (!IsPreamble())
1168  {
1169  if (DetectEncoding_Prop && ByteLen_Prop >= 2)
1170  {
1171  DetectEncoding();
1172  readToUserBuffer = (count >= MaxCharsPerBuffer_Prop);
1173  }
1174  CharPos_Prop = 0;
1175  if (readToUserBuffer)
1176  {
1177  i += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, buffer, index + charsRead);
1178  CharLen_Prop = 0;
1179  }
1180  else
1181  {
1182  i = Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, 0);
1183  CharLen_Prop += i;
1184  }
1185  }
1186  }
1187  while (i == 0);
1188  if (i == 0)
1189  {
1190  break;
1191  }
1192  }
1193  if (i > count)
1194  {
1195  i = count;
1196  }
1197  if (!readToUserBuffer)
1198  {
1199  Buffer.InternalBlockCopy(CharBuffer_Prop, CharPos_Prop * 2, buffer, (index + charsRead) * 2, i * 2);
1200  CharPos_Prop += i;
1201  }
1202  charsRead += i;
1203  count -= i;
1204  if (IsBlocked_Prop)
1205  {
1206  break;
1207  }
1208  }
1209  return charsRead;
1210  }
1211 
1224  [ComVisible(false)]
1225  [__DynamicallyInvokable]
1226  [HostProtection(SecurityAction.LinkDemand, ExternalThreading = true)]
1227  public override Task<int> ReadBlockAsync(char[] buffer, int index, int count)
1228  {
1229  if (buffer == null)
1230  {
1231  throw new ArgumentNullException("buffer", Environment.GetResourceString("ArgumentNull_Buffer"));
1232  }
1233  if (index < 0 || count < 0)
1234  {
1235  throw new ArgumentOutOfRangeException((index < 0) ? "index" : "count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
1236  }
1237  if (buffer.Length - index < count)
1238  {
1239  throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
1240  }
1241  if (GetType() != typeof(StreamReader))
1242  {
1243  return base.ReadBlockAsync(buffer, index, count);
1244  }
1245  if (stream == null)
1246  {
1247  __Error.ReaderClosed();
1248  }
1249  CheckAsyncTaskInProgress();
1250  return (Task<int>)(_asyncReadTask = base.ReadBlockAsync(buffer, index, count));
1251  }
1252 
1253  private async Task<int> ReadBufferAsync()
1254  {
1255  CharLen_Prop = 0;
1256  CharPos_Prop = 0;
1257  byte[] tmpByteBuffer = ByteBuffer_Prop;
1258  Stream tmpStream = Stream_Prop;
1259  if (!CheckPreamble_Prop)
1260  {
1261  ByteLen_Prop = 0;
1262  }
1263  do
1264  {
1265  if (CheckPreamble_Prop)
1266  {
1267  int bytePos_Prop = BytePos_Prop;
1268  int num = await tmpStream.ReadAsync(tmpByteBuffer, bytePos_Prop, tmpByteBuffer.Length - bytePos_Prop).ConfigureAwait(continueOnCapturedContext: false);
1269  if (num == 0)
1270  {
1271  if (ByteLen_Prop > 0)
1272  {
1273  CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop);
1274  BytePos_Prop = 0;
1275  ByteLen_Prop = 0;
1276  }
1277  return CharLen_Prop;
1278  }
1279  ByteLen_Prop += num;
1280  }
1281  else
1282  {
1283  ByteLen_Prop = await tmpStream.ReadAsync(tmpByteBuffer, 0, tmpByteBuffer.Length).ConfigureAwait(continueOnCapturedContext: false);
1284  if (ByteLen_Prop == 0)
1285  {
1286  return CharLen_Prop;
1287  }
1288  }
1289  IsBlocked_Prop = (ByteLen_Prop < tmpByteBuffer.Length);
1290  if (!IsPreamble())
1291  {
1292  if (DetectEncoding_Prop && ByteLen_Prop >= 2)
1293  {
1294  DetectEncoding();
1295  }
1296  CharLen_Prop += Decoder_Prop.GetChars(tmpByteBuffer, 0, ByteLen_Prop, CharBuffer_Prop, CharLen_Prop);
1297  }
1298  }
1299  while (CharLen_Prop == 0);
1300  return CharLen_Prop;
1301  }
1302  }
1303 }
Represents a character encoding.To browse the .NET Framework source code for this type,...
Definition: Encoding.cs:15
override Task< int > ReadAsync(char[] buffer, int index, int count)
Reads a specified maximum number of characters from the current stream asynchronously and writes the ...
The exception that is thrown when a null reference (Nothing in Visual Basic) is passed to a method th...
StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream,...
new ConfiguredTaskAwaitable< TResult > ConfigureAwait(bool continueOnCapturedContext)
Configures an awaiter used to await this T:System.Threading.Tasks.Task`1.
Definition: Task.cs:393
StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize, bool leaveOpen)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream based on th...
FileOptions
Represents advanced options for creating a T:System.IO.FileStream object.
Definition: FileOptions.cs:9
bool EndOfStream
Gets a value that indicates whether the current stream position is at the end of the stream.
unsafe override string ToString()
Converts the value of this instance to a T:System.String.
StreamReader(string path)
Initializes a new instance of the T:System.IO.StreamReader class for the specified file name.
FileMode
Specifies how the operating system should open a file.
Definition: FileMode.cs:8
static Encoding Unicode
Gets an encoding for the UTF-16 format using the little endian byte order.
Definition: Encoding.cs:975
abstract int GetMaxCharCount(int byteCount)
When overridden in a derived class, calculates the maximum number of characters produced by decoding ...
static new readonly StreamReader Null
A T:System.IO.StreamReader object around an empty stream.
Definition: StreamReader.cs:63
Definition: __Canon.cs:3
The exception that is thrown when the value of an argument is outside the allowable range of values a...
override string ReadToEnd()
Reads all characters from the current position to the end of the stream.
Implements a T:System.IO.TextReader that reads characters from a byte stream in a particular encoding...
Definition: StreamReader.cs:13
StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, int bufferSize)
Initializes a new instance of the T:System.IO.StreamReader class for the specified file name,...
override string ReadLine()
Reads a line of characters from the current stream and returns the data as a string.
virtual Decoder GetDecoder()
When overridden in a derived class, obtains a decoder that converts an encoded sequence of bytes into...
Definition: Encoding.cs:1953
Task< int > ReadAsync(byte[] buffer, int offset, int count)
Asynchronously reads a sequence of bytes from the current stream and advances the position within the...
Definition: Stream.cs:1032
StreamReader(Stream stream, Encoding encoding)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream,...
abstract bool CanRead
When overridden in a derived class, gets a value indicating whether the current stream supports readi...
Definition: Stream.cs:577
SecurityAction
Specifies the security actions that can be performed using declarative security.
Provides information about, and means to manipulate, the current environment and platform....
Definition: Environment.cs:21
override Task< int > ReadBlockAsync(char[] buffer, int index, int count)
Reads a specified maximum number of characters from the current stream asynchronously and writes the ...
StringBuilder Append(char value, int repeatCount)
Appends a specified number of copies of the string representation of a Unicode character to this inst...
static readonly Stream Null
A Stream with no backing store.
Definition: Stream.cs:562
Represents a UTF-16 encoding of Unicode characters.
override Task< string > ReadLineAsync()
Reads a line of characters asynchronously from the current stream and returns the data as a string.
override Task< string > ReadToEndAsync()
Reads all characters from the current position to the end of the stream asynchronously and returns th...
bool IsCompleted
Gets whether this T:System.Threading.Tasks.Task has completed.
Definition: Task.cs:1370
virtual Stream BaseStream
Returns the underlying stream.
Represents a UTF-32 encoding of Unicode characters.
Definition: UTF32Encoding.cs:8
Converts a sequence of encoded bytes into a set of characters.
Definition: Decoder.cs:11
void Dispose()
Releases all resources used by the T:System.IO.TextReader object.
Definition: TextReader.cs:173
StreamReader(string path, Encoding encoding)
Initializes a new instance of the T:System.IO.StreamReader class for the specified file name,...
Represents a mutable string of characters. This class cannot be inherited.To browse the ....
override int ReadBlock([In] [Out] char[] buffer, int index, int count)
Reads a specified maximum number of characters from the current stream and writes the data to a buffe...
StreamReader(Stream stream)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream.
The exception that is thrown when one of the arguments provided to a method is not valid.
virtual byte [] GetPreamble()
When overridden in a derived class, returns a sequence of bytes that specifies the encoding used.
Definition: Encoding.cs:1453
FileAccess
Defines constants for read, write, or read/write access to a file.
Definition: FileAccess.cs:9
override int Peek()
Returns the next available character but does not consume it.
StreamReader(Stream stream, bool detectEncodingFromByteOrderMarks)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream,...
Represents a reader that can read a sequential series of characters.
Definition: TextReader.cs:14
override int Read([In] [Out] char[] buffer, int index, int count)
Reads a specified maximum of characters from the current stream into a buffer, beginning at the speci...
void DiscardBufferedData()
Clears the internal buffer.
virtual Encoding CurrentEncoding
Gets the current character encoding that the current T:System.IO.StreamReader object is using.
abstract int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex)
When overridden in a derived class, decodes a sequence of bytes from the specified byte array and any...
Specifies that the class can be serialized.
static Encoding UTF8
Gets an encoding for the UTF-8 format.
Definition: Encoding.cs:1023
Manipulates arrays of primitive types.
Definition: Buffer.cs:11
override int Read()
Reads the next character from the input stream and advances the character position by one character.
StreamReader(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks)
Initializes a new instance of the T:System.IO.StreamReader class for the specified file name,...
The P:System.Uri.LocalPath data.
override void Close()
Closes the T:System.IO.StreamReader object and the underlying stream, and releases any system resourc...
override void Dispose(bool disposing)
Closes the underlying stream, releases the unmanaged resources used by the T:System....
StreamReader(string path, bool detectEncodingFromByteOrderMarks)
Initializes a new instance of the T:System.IO.StreamReader class for the specified file name,...
StreamReader(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks)
Initializes a new instance of the T:System.IO.StreamReader class for the specified stream,...
FileShare
Contains constants for controlling the kind of access other T:System.IO.FileStream objects can have t...
Definition: FileShare.cs:9
Represents an asynchronous operation that can return a value.
Definition: Task.cs:18
Provides a generic view of a sequence of bytes. This is an abstract class.To browse the ....
Definition: Stream.cs:16