2 // System.IO.StringReader
5 // Marcin Szczepanski (marcins@zipworld.com.au)
6 // Marek Safar (marek.safar@gmail.com)
8 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
9 // Copyright 2011 Xamarin Inc.
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System.Globalization;
34 using System.Runtime.InteropServices;
36 using System.Threading.Tasks;
42 public class StringReader : TextReader {
49 public StringReader (string s)
52 throw new ArgumentNullException ("s");
56 sourceLength = s.Length;
59 public override void Close ()
64 protected override void Dispose (bool disposing)
67 base.Dispose (disposing);
70 public override int Peek ()
73 ObjectDisposedException ();
75 if (nextChar >= sourceLength)
77 return (int)source [nextChar];
80 public override int Read ()
83 ObjectDisposedException ();
85 if (nextChar >= sourceLength)
87 return (int)source [nextChar++];
90 // The method will read up to count characters from the StringReader
91 // into the buffer character array starting at position index. Returns
92 // the actual number of characters read, or zero if the end of the string
93 // has been reached and no characters are read.
95 public override int Read ([In, Out] char[] buffer, int index, int count)
98 ObjectDisposedException ();
101 throw new ArgumentNullException ("buffer");
102 if (buffer.Length - index < count)
103 throw new ArgumentException ();
104 if (index < 0 || count < 0)
105 throw new ArgumentOutOfRangeException ();
109 // reordered to avoir possible integer overflow
110 if (nextChar > sourceLength - count)
111 charsToRead = sourceLength - nextChar;
115 source.CopyTo (nextChar, buffer, index, charsToRead);
117 nextChar += charsToRead;
122 public override string ReadLine ()
124 // Reads until next \r or \n or \r\n, otherwise return null
127 ObjectDisposedException ();
129 if (nextChar >= source.Length)
133 cr_lf = new char [] { '\n', '\r' };
135 int readto = source.IndexOfAny (cr_lf, nextChar);
140 bool consecutive = source[readto] == '\r'
141 && readto + 1 < source.Length
142 && source[readto + 1] == '\n';
144 string nextLine = source.Substring (nextChar, readto - nextChar);
145 nextChar = readto + ((consecutive) ? 2 : 1);
149 public override string ReadToEnd ()
152 ObjectDisposedException ();
153 string toEnd = source.Substring (nextChar, sourceLength - nextChar);
154 nextChar = sourceLength;
160 // All async methods return finished task with a result as it's faster
161 // than setting up async call
163 public override Task<int> ReadAsync (char[] buffer, int index, int count)
165 return Task.FromResult (Read (buffer, index, count));
168 public override Task<int> ReadBlockAsync (char[] buffer, int index, int count)
170 return Task.FromResult (ReadBlock (buffer, index, count));
173 public override Task<string> ReadLineAsync ()
175 return Task.FromResult (ReadLine ());
178 public override Task<string> ReadToEndAsync ()
180 return Task.FromResult (ReadToEnd ());
184 static void ObjectDisposedException ()
186 throw new ObjectDisposedException ("StringReader",
187 Locale.GetText ("Cannot read from a closed StringReader"));