Stream base_stream;
bool mayBlock;
+ StringBuilder line_builder;
private class NullStreamReader : StreamReader {
public override int Peek ()
}
}
+#if NET_2_0
+ public bool EndOfStream {
+ get { return Peek () < 0; }
+ }
+#endif
+
public override void Close ()
{
Dispose (true);
public void DiscardBufferedData ()
{
pos = decoded_count = 0;
+ mayBlock = false;
+ // Discard internal state of the decoder too.
+ decoder = encoding.GetDecoder ();
}
// the buffer is empty, fill it again
{
cbEncoded = base_stream.Read (input_buffer, 0, buffer_size);
- if (cbEncoded == 0)
+ if (cbEncoded <= 0)
return 0;
mayBlock = (cbEncoded < buffer_size);
return chars_read;
}
+ bool foundCR;
+ int FindNextEOL ()
+ {
+ char c = '\0';
+ for (; pos < decoded_count; pos++) {
+ c = decoded_buffer [pos];
+ if (c == '\n') {
+ pos++;
+ int res = (foundCR) ? (pos - 2) : (pos - 1);
+ if (res < 0)
+ res = 0; // if a new buffer starts with a \n and there was a \r at
+ // the end of the previous one, we get here.
+ foundCR = false;
+ return res;
+ } else if (foundCR) {
+ foundCR = false;
+ return pos - 1;
+ }
+
+ foundCR = (c == '\r');
+ }
+
+ return -1;
+ }
+
public override string ReadLine()
{
if (base_stream == null)
throw new ObjectDisposedException ("StreamReader", "Cannot read from a closed StreamReader");
-
- bool foundCR = false;
- StringBuilder text = new StringBuilder ();
- while (true) {
- int c = Read ();
+ if (pos >= decoded_count && ReadBuffer () == 0)
+ return null;
- if (c == -1) { // end of stream
- if (text.Length == 0)
- return null;
+ int begin = pos;
+ int end = FindNextEOL ();
+ if (end < decoded_count && end >= begin)
+ return new string (decoded_buffer, begin, end - begin);
- if (foundCR)
- text.Length--;
+ if (line_builder == null)
+ line_builder = new StringBuilder ();
+ else
+ line_builder.Length = 0;
- break;
+ while (true) {
+ if (foundCR) // don't include the trailing CR if present
+ decoded_count--;
+
+ line_builder.Append (decoded_buffer, begin, decoded_count - begin);
+ if (ReadBuffer () == 0) {
+ if (line_builder.Capacity > 32768) {
+ StringBuilder sb = line_builder;
+ line_builder = null;
+ return sb.ToString (0, sb.Length);
+ }
+ return line_builder.ToString (0, line_builder.Length);
}
- if (c == '\n') { // newline
- if ((text.Length > 0) && (text [text.Length - 1] == '\r'))
- text.Length--;
-
- foundCR = false;
- break;
- } else if (foundCR) {
- pos--;
- text.Length--;
- break;
+ begin = pos;
+ end = FindNextEOL ();
+ if (end < decoded_count && end >= begin) {
+ line_builder.Append (decoded_buffer, begin, end - begin);
+ if (line_builder.Capacity > 32768) {
+ StringBuilder sb = line_builder;
+ line_builder = null;
+ return sb.ToString (0, sb.Length);
+ }
+ return line_builder.ToString (0, line_builder.Length);
}
-
- if (c == '\r')
- foundCR = true;
-
-
- text.Append ((char) c);
}
-
- return text.ToString ();
}
public override string ReadToEnd()
char [] buffer = new char [size];
int len;
- while ((len = Read (buffer, 0, size)) != 0)
+ while ((len = Read (buffer, 0, size)) > 0)
text.Append (buffer, 0, len);
return text.ToString ();