Merge pull request #309 from i59/patch-1
[mono.git] / mcs / class / corlib / System.IO / UnexceptionalStreamReader.cs
1 //
2 // System.IO.UnexceptionalStreamReader.cs
3 //
4 // Authors:
5 //   Dietmar Maurer (dietmar@ximian.com)
6 //   Miguel de Icaza (miguel@ximian.com)
7 //   Dick Porter (dick@ximian.com)
8 //   Sebastien Pouliot  <sebastien@ximian.com>
9 //
10 // (C) Ximian, Inc.  http://www.ximian.com
11 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 //
32
33
34 // This is a wrapper around StreamReader used by System.Console that
35 // catches IOException so that graphical applications don't suddenly
36 // get IO errors when their terminal vanishes.  See
37 // UnexceptionalStreamWriter too.
38
39 using System.Text;
40 using System.Runtime.InteropServices;
41
42 namespace System.IO {
43         internal class UnexceptionalStreamReader : StreamReader {
44
45                 private static bool[] newline = new bool [Environment.NewLine.Length];
46
47                 private static char newlineChar;
48
49                 static UnexceptionalStreamReader () {
50                         string n = Environment.NewLine;
51                         if (n.Length == 1)
52                                 newlineChar = n [0];
53                 }
54 /*
55                 public UnexceptionalStreamReader(Stream stream)
56                         : base (stream)
57                 {
58                 }
59
60                 public UnexceptionalStreamReader(Stream stream, bool detect_encoding_from_bytemarks)
61                         : base (stream, detect_encoding_from_bytemarks)
62                 {
63                 }
64 */
65                 public UnexceptionalStreamReader(Stream stream, Encoding encoding)
66                         : base (stream, encoding)
67                 {
68                 }
69 /*
70                 public UnexceptionalStreamReader(Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks)
71                         : base (stream, encoding, detect_encoding_from_bytemarks)
72                 {
73                 }
74                 
75                 public UnexceptionalStreamReader(Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks, int buffer_size)
76                         : base (stream, encoding, detect_encoding_from_bytemarks, buffer_size)
77                 {
78                 }
79
80                 public UnexceptionalStreamReader(string path)
81                         : base (path)
82                 {
83                 }
84
85                 public UnexceptionalStreamReader(string path, bool detect_encoding_from_bytemarks)
86                         : base (path, detect_encoding_from_bytemarks)
87                 {
88                 }
89
90                 public UnexceptionalStreamReader(string path, Encoding encoding)
91                         : base (path, encoding)
92                 {
93                 }
94
95                 public UnexceptionalStreamReader(string path, Encoding encoding, bool detect_encoding_from_bytemarks)
96                         : base (path, encoding, detect_encoding_from_bytemarks)
97                 {
98                 }
99                 
100                 public UnexceptionalStreamReader(string path, Encoding encoding, bool detect_encoding_from_bytemarks, int buffer_size)
101                         : base (path, encoding, detect_encoding_from_bytemarks, buffer_size)
102                 {
103                 }
104 */
105                 public override int Peek ()
106                 {
107                         try {
108                                 return(base.Peek ());
109                         } catch (IOException) {
110                         }
111
112                         return(-1);
113                 }
114
115                 public override int Read ()
116                 {
117                         try {
118                                 return(base.Read ());
119                         } catch (IOException) {
120                         }
121
122                         return(-1);
123                 }
124
125                 public override int Read ([In, Out] char[] dest_buffer,
126                                           int index, int count)
127                 {
128                         if (dest_buffer == null)
129                                 throw new ArgumentNullException ("dest_buffer");
130                         if (index < 0)
131                                 throw new ArgumentOutOfRangeException ("index", "< 0");
132                         if (count < 0)
133                                 throw new ArgumentOutOfRangeException ("count", "< 0");
134                         // ordered to avoid possible integer overflow
135                         if (index > dest_buffer.Length - count)
136                                 throw new ArgumentException ("index + count > dest_buffer.Length");
137
138                         int chars_read = 0;
139                         char nl = newlineChar;
140                         try {
141                                 while (count > 0) {
142                                         int c = base.Read ();
143                                         if (c < 0)
144                                                 break;
145                                         chars_read++;
146                                         count--;
147
148                                         dest_buffer [index] = (char) c;
149                                         // shortcut when a new line is only one character (e.g. Linux, Mac)
150                                         if (nl != (char)0) {
151                                                 if ((char)c == nl)
152                                                         return chars_read;
153                                         } else {
154                                                 if (CheckEOL ((char)c))
155                                                         return chars_read;
156                                         }
157                                         index ++;
158                                 }
159                         } catch (IOException) {
160                         }
161                         
162                         return chars_read;
163                 }
164
165                 private bool CheckEOL (char current)
166                 {
167                         // general case for any length (e.g. Windows)
168                         for (int i=0; i < newline.Length; i++) {
169                                 if (!newline [i]) {
170                                         if (current == Environment.NewLine [i]) {
171                                                 newline [i] = true;
172                                                 return (i == newline.Length - 1);
173                                         }
174                                         break;
175                                 }
176                         }
177                         for (int j=0; j < newline.Length; j++)
178                                 newline [j] = false;
179                         return false;
180                 }
181
182                 public override string ReadLine()
183                 {
184                         try {
185                                 return(base.ReadLine ());
186                         } catch (IOException) {
187                         }
188
189                         return(null);
190                 }
191
192                 public override string ReadToEnd()
193                 {
194                         try {
195                                 return(base.ReadToEnd ());
196                         } catch (IOException) {
197                         }
198
199                         return(null);
200                 }
201         }
202 }