StringReader.cs 4.2 KB

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