StringReader.cs 3.7 KB

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