StringReader.cs 3.6 KB

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