1
2
3
4
5
6 using System;
7 using System.Collections;
8
9 namespace System.IO
10 {
11 public class StreamReader : IOBase
12 {
13 public StreamReader() : base(), stream(null), buffer(-1), buffered(false), eos(false)
14 {
15 }
16 public explicit StreamReader(Stream* stream_) : base(), stream(stream_), buffer(-1), buffered(false), eos(false)
17 {
18 if (stream != null && stream->Error())
19 {
20 SetErrorId(stream->GetErrorId());
21 }
22 }
23 suppress StreamReader(const StreamReader&);
24 suppress void operator=(const StreamReader&);
25 public StreamReader(StreamReader&& that) : base(), stream(that.stream), streams(Rvalue(that.streams)), buffer(that.buffer), buffered(that.buffered), eos(that.eos)
26 {
27 that.stream = null;
28 }
29 public default void operator=(StreamReader&&);
30 public override ~StreamReader()
31 {
32 long n = streams.Count();
33 for (long i = n - 1; i >= 0; --i;)
34 {
35 streams[i].Reset();
36 }
37 }
38 public inline Stream* GetStream()
39 {
40 return stream;
41 }
42 public void SetStream(Stream* stream_)
43 {
44 stream = stream_;
45 if (stream != null && stream->Error())
46 {
47 SetErrorId(stream->GetErrorId());
48 }
49 }
50 public void Own(Stream* strm)
51 {
52 streams.Add(UniquePtr<Stream>(strm));
53 }
54 [nodiscard]
55 public Result<int> Read()
56 {
57 auto x = Get(false);
58 if (x.Error())
59 {
60 return Result<int>(ErrorId(x.GetErrorId()));
61 }
62 eos = x.Value() == -1;
63 return Result<int>(x.Value());
64 }
65 [nodiscard]
66 public Result<int> Peek()
67 {
68 auto x = Get(true);
69 if (x.Error())
70 {
71 return Result<int>(ErrorId(x.GetErrorId()));
72 }
73 eos = x.Value() == -1;
74 return Result<int>(x.Value());
75 }
76 [nodiscard]
77 public Result<string> ReadLine()
78 {
79 string result;
80 auto x = Read();
81 if (x.Error())
82 {
83 return Result<string>(ErrorId(x.GetErrorId()));
84 }
85 bool prevWasCR = false;
86 while (x.Value() != -1)
87 {
88 if (cast<char>(x.Value()) == '\r')
89 {
90 if (prevWasCR)
91 {
92 result.Append('\r');
93 }
94 prevWasCR = true;
95 }
96 else if (cast<char>(x.Value()) == '\n')
97 {
98 return Result<string>(result);
99 }
100 else
101 {
102 if (prevWasCR)
103 {
104 result.Append('\r');
105 prevWasCR = false;
106 }
107 result.Append(cast<char>(x.Value()));
108 }
109 x = Read();
110 if (x.Error())
111 {
112 return Result<string>(ErrorId(x.GetErrorId()));
113 }
114 }
115 eos = true;
116 if (prevWasCR)
117 {
118 result.Append('\r');
119 }
120 return Result<string>(result);
121 }
122 [nodiscard]
123 public Result<string> ReadToEnd()
124 {
125 string result;
126 auto x = Read();
127 if (x.Error())
128 {
129 return Result<string>(ErrorId(x.GetErrorId()));
130 }
131 while (x.Value() != -1)
132 {
133 result.Append(cast<char>(x.Value()));
134 x = Read();
135 if (x.Error())
136 {
137 return Result<string>(ErrorId(x.GetErrorId()));
138 }
139 }
140 eos = true;
141 return Result<string>(result);
142 }
143 public void PutBack(byte b)
144 {
145 buffered = true;
146 buffer = b;
147 }
148 [nodiscard]
149 private Result<int> Get(bool peek)
150 {
151 if (buffered)
152 {
153 if (!peek)
154 {
155 buffered = false;
156 }
157 return Result<int>(buffer);
158 }
159 else
160 {
161 if (stream == null)
162 {
163 int errorId = RtmAllocateError("StreamReader.Get: stream is null");
164 SetErrorId(errorId);
165 return Result<int>(ErrorId(errorId));
166 }
167 auto x = stream->ReadByte();
168 if (x.Error())
169 {
170 SetErrorId(x.GetErrorId());
171 return Result<int>(ErrorId(x.GetErrorId()));
172 }
173 if (peek)
174 {
175 buffer = x.Value();
176 buffered = true;
177 }
178 return Result<int>(x.Value());
179 }
180 }
181 public inline bool Buffered() const
182 {
183 return buffered;
184 }
185 public inline bool EndOfStream() const
186 {
187 return eos;
188 }
189 private Stream* stream;
190 private List<UniquePtr<Stream>> streams;
191 private int buffer;
192 private bool buffered;
193 private bool eos;
194 }