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