1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public class StreamReader
 11     {
 12         public nothrow StreamReader(const SharedPtr<Stream>& stream_) : stream(stream_)buffered(false)buffer(-1)state(0)eos(false)
 13         {
 14         }
 15         public int Read()
 16         {
 17             int x = Get(false);
 18             eos = x == -1;
 19             return x;
 20         }
 21         public int Peek()
 22         {
 23             int x = Get(true);
 24             eos = x == -1;
 25             return x;
 26         }
 27         public string ReadLine()
 28         {
 29             string result;
 30             int x = Read();
 31             while (x != -1)
 32             {
 33                 if (cast<char>(x) == '\n')
 34                 {
 35                     return result;
 36                 }
 37                 else
 38                 {
 39                     result.Append(cast<char>(x));
 40                 }
 41                 x = Read();
 42             }
 43             eos = true;
 44             if (state == 1)
 45             {
 46                 result.Append('\r');
 47             }
 48             return result;
 49         }
 50         public string ReadToEnd()
 51         {
 52             string result;
 53             int x = Read();
 54             while (x != -1)
 55             {
 56                 result.Append(cast<char>(x));
 57                 x = Read();
 58             }
 59             eos = true;
 60             if (state == 1)
 61             {
 62                 result.Append('\r');
 63             }
 64             return result;
 65         }
 66         public void PutBack(byte b)
 67         {
 68             buffered = true;
 69             buffer = b;
 70         }
 71         private int Get(bool peek)
 72         {
 73             if (buffered)
 74             {
 75                 if (!peek)
 76                 {
 77                     buffered = false;
 78                 }
 79                 return buffer;
 80             }
 81             else
 82             {
 83                 while (true)
 84                 {
 85                     int x = stream->ReadByte();
 86                     switch (state)
 87                     {
 88                         case 0:
 89                         {
 90                             if (cast<char>(x) == '\r')
 91                             {
 92                                 state = 1;
 93                             }
 94                             else
 95                             {
 96                                 if (peek)
 97                                 {
 98                                     buffer = x;
 99                                     buffered = true;
100                                 }
101                                 return x;
102                             }
103                             break;
104                         }
105                         case 1:
106                         {
107                             if (cast<char>(x) == '\r')
108                             {
109                                 if (peek)
110                                 {
111                                     buffer = x;
112                                     buffered = true;
113                                 }
114                                 return x;
115                             }
116                             else if (cast<char>(x) == '\n')
117                             {
118                                 state = 0;
119                                 if (peek)
120                                 {
121                                     buffer = x;
122                                     buffered = true;
123                                 }
124                                 return x;
125                             }
126                             else
127                             {
128                                 state = 0;
129                                 buffer = x;
130                                 buffered = true;
131                                 return cast<int>('\r');
132                             }
133                             break;
134                         }
135                     }
136                 }
137             }
138             return -1;
139         }
140         public inline nothrow bool EndOfStream() const
141         {
142             return eos;
143         }
144         public inline nothrow void ResetEndOfStream()
145         {
146             eos = false;
147         }
148         public nothrow const SharedPtr<Stream>& GetStream() const
149         {
150             return stream;
151         }
152         private SharedPtr<Stream> stream;
153         private bool buffered;
154         private int buffer;
155         private int state;
156         private bool eos;
157     }
158 }