2 // System.IO.TextReader
5 // Marcin Szczepanski (marcins@zipworld.com.au)
6 // Miguel de Icaza (miguel@gnome.org)
7 // Marek Safar (marek.safar@gmail.com)
10 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
11 // Copyright 2011 Xamarin Inc.
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:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
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.
34 using System.Runtime.InteropServices;
36 using System.Threading.Tasks;
44 public abstract class TextReader : IDisposable {
46 public abstract class TextReader : MarshalByRefObject, IDisposable {
49 sealed class NullTextReader : TextReader
51 public override string ReadLine ()
56 public override string ReadToEnd ()
62 public static readonly TextReader Null = new NullTextReader ();
64 protected TextReader()
68 public virtual void Close()
73 public void Dispose ()
78 protected virtual void Dispose (bool disposing)
81 // If we are explicitly disposed, we can avoid finalization.
82 GC.SuppressFinalize (this);
87 public virtual int Peek()
92 public virtual int Read()
97 public virtual int Read ([In, Out] char[] buffer, int index, int count)
101 for (i = 0; i < count; i++) {
102 if ((c = Read ()) == -1)
104 buffer [index + i] = (char)c;
110 public virtual int ReadBlock ([In, Out] char [] buffer, int index, int count)
112 int total_read_count = 0;
113 int current_read_count = 0;
116 current_read_count = Read (buffer, index, count);
117 index += current_read_count;
118 total_read_count += current_read_count;
119 count -= current_read_count;
120 } while (current_read_count != 0 && count > 0);
122 return total_read_count;
125 public virtual string ReadLine ()
127 var result = new System.Text.StringBuilder ();
130 while ((c = Read ()) != -1){
131 // check simple character line ending
139 result.Append ((char) c);
141 if (c == -1 && result.Length == 0)
144 return result.ToString ();
147 public virtual string ReadToEnd ()
149 var result = new System.Text.StringBuilder ();
151 while ((c = Read ()) != -1)
152 result.Append ((char) c);
153 return result.ToString ();
156 public static TextReader Synchronized (TextReader reader)
159 throw new ArgumentNullException ("reader is null");
160 if (reader is SynchronizedReader)
163 return new SynchronizedReader (reader);
168 // Use tuple to pack the arguments because it's faster than
169 // setting up anonymous method container with an instance delegate
171 public virtual Task<int> ReadAsync (char[] buffer, int index, int count)
173 return Task.Factory.StartNew (l => {
174 var t = (Tuple<TextReader, char[], int, int>) l;
175 return t.Item1.Read (t.Item2, t.Item3, t.Item4);
176 }, Tuple.Create (this, buffer, index, count));
179 public virtual Task<int> ReadBlockAsync (char[] buffer, int index, int count)
181 return Task.Factory.StartNew (l => {
182 var t = (Tuple<TextReader, char[], int, int>) l;
183 return t.Item1.ReadBlock (t.Item2, t.Item3, t.Item4);
184 }, Tuple.Create (this, buffer, index, count));
187 public virtual Task<string> ReadLineAsync ()
189 return Task.Factory.StartNew (l => ((TextReader) l).ReadLine (), this);
192 public virtual Task<string> ReadToEndAsync ()
194 return Task.Factory.StartNew (l => ((TextReader) l).ReadToEnd (), this);
200 // Synchronized Reader implementation, used internally.
203 sealed class SynchronizedReader : TextReader
205 readonly TextReader reader;
207 public SynchronizedReader (TextReader reader)
209 this.reader = reader;
212 public override void Close ()
219 public override int Peek ()
222 return reader.Peek ();
226 public override int ReadBlock (char [] buffer, int index, int count)
229 return reader.ReadBlock (buffer, index, count);
233 public override string ReadLine ()
236 return reader.ReadLine ();
240 public override string ReadToEnd ()
243 return reader.ReadToEnd ();
247 public override int Read ()
250 return reader.Read ();
254 public override int Read (char [] buffer, int index, int count)
257 return reader.Read (buffer, index, count);
262 public override Task<int> ReadAsync (char[] buffer, int index, int count)
265 return reader.ReadAsync (buffer, index, count);
269 public override Task<int> ReadBlockAsync (char[] buffer, int index, int count)
272 return reader.ReadBlockAsync (buffer, index, count);
276 public override Task<string> ReadLineAsync ()
279 return reader.ReadLineAsync ();
283 public override Task<string> ReadToEndAsync ()
286 return reader.ReadToEndAsync ();