StringReader.cs 3.6 KB

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