2003-02-11 Gonzalo Paniagua Javier <gonzalo@ximian.com>
[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                 {
33                         sourceChars = null;
34                         base.Dispose (disposing);
35                 }
36
37                 public override int Peek() {
38                         if( nextChar >= sourceLength ) {
39                                 return -1;
40                         } else {
41                                 return (int)source[ nextChar ];
42                         }
43                 }
44
45                 public override int Read() {
46                         if( nextChar >= sourceLength ) {
47                                 return -1;
48                         } else {
49                                 return (int)source[ nextChar++ ];
50                         }
51                 }
52
53
54                 // The method will read up to count characters from the StringReader
55                 // into the buffer character array starting at position index. Returns
56                 // the actual number of characters read, or zero if the end of the string
57                 // has been reached and no characters are read.
58
59                 public override int Read( char[] buffer, int index, int count ) {
60
61                         if( buffer == null ) {
62                                 throw new ArgumentNullException();
63                         } else if( buffer.Length - index < count ) {
64                                 throw new ArgumentException();
65                         } else if( index < 0 || count < 0 ) {
66                                 throw new ArgumentOutOfRangeException();
67                         }
68
69                         int charsToRead;
70
71                         if( nextChar + count > sourceLength ) {
72                                 charsToRead = sourceLength - nextChar;
73                         } else {
74                                 charsToRead = count;
75                         }
76
77                         Array.Copy(sourceChars, nextChar, buffer, index, charsToRead );
78
79                         nextChar += count;
80
81                         return charsToRead;
82                 }
83
84                 public override string ReadLine() {
85                         // Reads until next \r or \n or \r\n, otherwise return null
86
87                         // LAMESPEC:
88                         // The Beta 2 SDK help says that the ReadLine method returns
89                         // "The next line from the input stream [...] A line is defined as a sequence of
90                         // characters followed by a carriage return (\r), a line feed (\n), or a carriage
91                         // return immediately followed by a line feed (\r\n). [...]
92                         // The returned value is a null reference if the end of the input stream has been reached."
93                         //
94                         // HOWEVER, the MS implementation returns the rest of the string if no \r and/or \n is found
95                         // in the string
96
97                         if (nextChar >= source.Length)
98                                 return null;
99
100                         int nextCR = source.IndexOf( '\r', nextChar );
101                         int nextLF = source.IndexOf( '\n', nextChar );
102
103                         if( nextCR == -1 && nextLF == -1 ) {
104                                 return ReadToEnd();
105                         }
106
107                         int readTo;
108
109                         if( nextCR == -1 ) {
110                                 readTo = nextLF;
111                         } else {
112                                 readTo = nextCR;
113                         }
114
115                         string nextLine = source.Substring( nextChar, readTo - nextChar );
116
117                         if( nextLF == nextCR + 1 ) {
118                                 nextChar = readTo + 2;
119                         } else {
120                                 nextChar = readTo + 1;
121                         }
122
123                         return nextLine;
124                 }
125
126                 public override string ReadToEnd() {
127                         string toEnd = source.Substring( nextChar, sourceLength - nextChar );
128                         nextChar = sourceLength;
129                         return toEnd;
130                 }
131
132         }
133 }