StringReader.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. //
  2. // System.IO.StringReader
  3. //
  4. // Author: Marcin Szczepanski ([email protected])
  5. //
  6. using System;
  7. using System.Runtime.InteropServices;
  8. namespace System.IO {
  9. [Serializable]
  10. public class StringReader : TextReader {
  11. private string source;
  12. private char[] sourceChars;
  13. private int nextChar;
  14. private int sourceLength;
  15. private bool disposed = false;
  16. public StringReader( string s ) {
  17. if (s == null)
  18. throw new ArgumentNullException ();
  19. this.source = s;
  20. nextChar = 0;
  21. sourceLength = s.Length;
  22. sourceChars = s.ToCharArray();
  23. }
  24. public override void Close() {
  25. Dispose( true );
  26. disposed = true;
  27. }
  28. protected override void Dispose (bool disposing)
  29. {
  30. sourceChars = null;
  31. base.Dispose (disposing);
  32. }
  33. public override int Peek() {
  34. CheckObjectDisposedException ();
  35. if( nextChar >= sourceLength ) {
  36. return -1;
  37. } else {
  38. return (int)source[ nextChar ];
  39. }
  40. }
  41. public override int Read() {
  42. CheckObjectDisposedException ();
  43. if( nextChar >= sourceLength ) {
  44. return -1;
  45. } else {
  46. return (int)source[ nextChar++ ];
  47. }
  48. }
  49. // The method will read up to count characters from the StringReader
  50. // into the buffer character array starting at position index. Returns
  51. // the actual number of characters read, or zero if the end of the string
  52. // has been reached and no characters are read.
  53. public override int Read ([In, Out] char[] buffer, int index, int count )
  54. {
  55. CheckObjectDisposedException ();
  56. if( buffer == null ) {
  57. throw new ArgumentNullException();
  58. } else if( buffer.Length - index < count ) {
  59. throw new ArgumentException();
  60. } else if( index < 0 || count < 0 ) {
  61. throw new ArgumentOutOfRangeException();
  62. }
  63. int charsToRead;
  64. if( nextChar + count > sourceLength ) {
  65. charsToRead = sourceLength - nextChar;
  66. } else {
  67. charsToRead = count;
  68. }
  69. Array.Copy(sourceChars, nextChar, buffer, index, charsToRead );
  70. nextChar += charsToRead;
  71. return charsToRead;
  72. }
  73. public override string ReadLine ()
  74. {
  75. // Reads until next \r or \n or \r\n, otherwise return null
  76. // LAMESPEC:
  77. // The Beta 2 SDK help says that the ReadLine method
  78. // returns "The next line from the input stream [...] A
  79. // line is defined as a sequence of characters followed by
  80. // a carriage return (\r), a line feed (\n), or a carriage
  81. // return immediately followed by a line feed (\r\n).
  82. // [...] The returned value is a null reference if the end
  83. // of the input stream has been reached."
  84. //
  85. // HOWEVER, the MS implementation returns the rest of
  86. // the string if no \r and/or \n is found in the string
  87. if (disposed)
  88. throw new ObjectDisposedException ("StringReader",
  89. "Cannot read from a closed StringReader");
  90. if (nextChar >= source.Length)
  91. return null;
  92. int nextCR = source.IndexOf ('\r', nextChar);
  93. int nextLF = source.IndexOf ('\n', nextChar);
  94. int readTo;
  95. bool consecutive = false;
  96. if (nextCR == -1) {
  97. if (nextLF == -1)
  98. return ReadToEnd ();
  99. readTo = nextLF;
  100. } else if (nextLF == -1) {
  101. readTo = nextCR;
  102. } else {
  103. readTo = (nextCR > nextLF) ? nextLF : nextCR;
  104. consecutive = (nextCR + 1 == nextLF || nextLF + 1 == nextCR);
  105. }
  106. string nextLine = source.Substring (nextChar, readTo - nextChar);
  107. nextChar = readTo + ((consecutive) ? 2 : 1);
  108. return nextLine;
  109. }
  110. public override string ReadToEnd() {
  111. CheckObjectDisposedException ();
  112. string toEnd = source.Substring( nextChar, sourceLength - nextChar );
  113. nextChar = sourceLength;
  114. return toEnd;
  115. }
  116. private void CheckObjectDisposedException ()
  117. {
  118. if (disposed)
  119. throw new ObjectDisposedException ("StringReader", "Cannot read from a closed StringReader");
  120. }
  121. }
  122. }