1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 using System.Collections;
  8 
  9 namespace System.IO
 10 {
 11     public class StreamWriter : TextWriter
 12     {
 13         public StreamWriter() : base()stream(null)
 14         {
 15         }
 16         public explicit StreamWriter(Stream* stream_) : base()stream(stream_)
 17         {
 18             if (stream != null && stream->Error())
 19             {
 20                 SetErrorId(stream->GetErrorId());
 21             }
 22         }
 23         public override ~StreamWriter()
 24         {
 25             if (stream != null)
 26             {
 27                 auto result = Flush();
 28             }
 29             long n = streams.Count();
 30             for (long i = n - 1; i >= 0; --i;)
 31             {
 32                 streams[i].Reset();
 33             }
 34         }
 35         suppress StreamWriter(const StreamWriter&);
 36         suppress void operator=(const StreamWriter&);
 37         public StreamWriter(StreamWriter&& that) : stream(that.stream)streams(Rvalue(that.streams))
 38         {
 39             that.stream = null;
 40         }
 41         public default void operator=(StreamWriter&&);
 42         public inline Stream* GetStream()
 43         {
 44             return stream;
 45         }
 46         public void SetStream(Stream* stream_)
 47         {
 48             stream = stream_;
 49             if (stream != null && stream->Error())
 50             {
 51                 SetErrorId(stream->GetErrorId());
 52             }
 53         }
 54         public void Own(Stream* strm)
 55         {
 56             streams.Add(UniquePtr<Stream>(strm));
 57         }
 58         [nodiscard]
 59         public Result<bool> Write(const char* xlong length)
 60         {
 61             if (Error())
 62             {
 63                 return Result<bool>(ErrorId(GetErrorId()));
 64             }
 65             if (stream == null)
 66             {
 67                 int errorId = RtmAllocateError("StreamWriter.Write: stream is null");
 68                 SetErrorId(errorId);
 69                 return Result<bool>(ErrorId(errorId));
 70             }
 71             void* buf = x;
 72             auto result = stream->Write(cast<byte*>(buf)length);
 73             if (result.Error())
 74             {
 75                 SetErrorId(result.GetErrorId());
 76             }
 77             return result;
 78         }
 79         [nodiscard]
 80         public override Result<bool> Write(const string& x)
 81         {
 82             return Write(x.Chars()x.Length());
 83         }
 84         [nodiscard]
 85         public override Result<bool> Write(const wstring& x)
 86         {
 87             auto result = ToUtf8(x);
 88             if (result.Error())
 89             {
 90                 return Result<bool>(ErrorId(result.GetErrorId()));
 91             }
 92             return Write(result.Value());
 93         }
 94         [nodiscard]
 95         public override Result<bool> Write(const ustring& x)
 96         {
 97             auto result = ToUtf8(x);
 98             if (result.Error())
 99             {
100                 return Result<bool>(ErrorId(result.GetErrorId()));
101             }
102             return Write(result.Value());
103         }
104         [nodiscard]
105         public override Result<bool> Write(bool x)
106         {
107             return Write(ToString(x));
108         }
109         [nodiscard]
110         public override Result<bool> Write(char x)
111         {
112             return Write(ToString(x));
113         }
114         [nodiscard]
115         public override Result<bool> Write(wchar x)
116         {
117             auto result = ToString(x);
118             if (result.Error())
119             {
120                 return Result<bool>(ErrorId(result.GetErrorId()));
121             }
122             return Write(result.Value());
123         }
124         [nodiscard]
125         public override Result<bool> Write(uchar x)
126         {
127             auto result = ToString(x);
128             if (result.Error())
129             {
130                 return Result<bool>(ErrorId(result.GetErrorId()));
131             }
132             return Write(result.Value());
133         }
134         [nodiscard]
135         public override Result<bool> Write(sbyte x)
136         {
137             return Write(ToString(x));
138         }
139         [nodiscard]
140         public override Result<bool> Write(byte x)
141         {
142             return Write(ToString(x));
143         }
144         [nodiscard]
145         public override Result<bool> Write(short x)
146         {
147             return Write(ToString(x));
148         }
149         [nodiscard]
150         public override Result<bool> Write(ushort x)
151         {
152             return Write(ToString(x));
153         }
154         [nodiscard]
155         public override Result<bool> Write(int x)
156         {
157             return Write(ToString(x));
158         }
159         [nodiscard]
160         public override Result<bool> Write(uint x)
161         {
162             return Write(ToString(x));
163         }
164         [nodiscard]
165         public override Result<bool> Write(long x)
166         {
167             return Write(ToString(x));
168         }
169         [nodiscard]
170         public override Result<bool> Write(ulong x)
171         {
172             return Write(ToString(x));
173         }
174         [nodiscard]
175         public override Result<bool> Write(float x)
176         {
177             return Write(ToString(x));
178         }
179         [nodiscard]
180         public override Result<bool> Write(double x)
181         {
182             return Write(ToString(x));
183         }
184         [nodiscard]
185         public override Result<bool> Write(const Date& date)
186         {
187             return Write(date.ToString());
188         }
189         [nodiscard]
190         public override Result<bool> Write(const DateTime& dateTime)
191         {
192             return Write(dateTime.ToString());
193         }
194         [nodiscard]
195         public override Result<bool> WriteLine()
196         {
197             return Write("\n"1);
198         }
199         [nodiscard]
200         public override Result<bool> WriteLine(const string& x)
201         {
202             auto result = Write(x);
203             return result.AndThen(WriteLine());
204         }
205         [nodiscard]
206         public override Result<bool> WriteLine(const wstring& x)
207         {
208             auto result = Write(x);
209             return result.AndThen(WriteLine());
210         }
211         [nodiscard]
212         public override Result<bool> WriteLine(const ustring& x)
213         {
214             auto result = Write(x);
215             return result.AndThen(WriteLine());
216         }
217         [nodiscard]
218         public override Result<bool> WriteLine(bool x)
219         {
220             auto result = Write(x);
221             return result.AndThen(WriteLine());
222         }
223         [nodiscard]
224         public override Result<bool> WriteLine(char x)
225         {
226             auto result = Write(x);
227             return result.AndThen(WriteLine());
228         }
229         [nodiscard]
230         public override Result<bool> WriteLine(wchar x)
231         {
232             auto result = Write(x);
233             return result.AndThen(WriteLine());
234         }
235         [nodiscard]
236         public override Result<bool> WriteLine(uchar x)
237         {
238             auto result = Write(x);
239             return result.AndThen(WriteLine());
240         }
241         [nodiscard]
242         public override Result<bool> WriteLine(sbyte x)
243         {
244             auto result = Write(x);
245             return result.AndThen(WriteLine());
246         }
247         [nodiscard]
248         public override Result<bool> WriteLine(byte x)
249         {
250             auto result = Write(x);
251             return result.AndThen(WriteLine());
252         }
253         [nodiscard]
254         public override Result<bool> WriteLine(short x)
255         {
256             auto result = Write(x);
257             return result.AndThen(WriteLine());
258         }
259         [nodiscard]
260         public override Result<bool> WriteLine(ushort x)
261         {
262             auto result = Write(x);
263             return result.AndThen(WriteLine());
264         }
265         [nodiscard]
266         public override Result<bool> WriteLine(int x)
267         {
268             auto result = Write(x);
269             return result.AndThen(WriteLine());
270         }
271         [nodiscard]
272         public override Result<bool> WriteLine(uint x)
273         {
274             auto result = Write(x);
275             return result.AndThen(WriteLine());
276         }
277         [nodiscard]
278         public override Result<bool> WriteLine(long x)
279         {
280             auto result = Write(x);
281             return result.AndThen(WriteLine());
282         }
283         [nodiscard]
284         public override Result<bool> WriteLine(ulong x)
285         {
286             auto result = Write(x);
287             return result.AndThen(WriteLine());
288         }
289         [nodiscard]
290         public override Result<bool> WriteLine(float x)
291         {
292             auto result = Write(x);
293             return result.AndThen(WriteLine());
294         }
295         [nodiscard]
296         public override Result<bool> WriteLine(double x)
297         {
298             auto result = Write(x);
299             return result.AndThen(WriteLine());
300         }
301         [nodiscard]
302         public override Result<bool> WriteLine(const Date& date)
303         {
304             auto result = Write(date);
305             return result.AndThen(WriteLine());
306         }
307         [nodiscard]
308         public override Result<bool> WriteLine(const DateTime& dateTime)
309         {
310             auto result = Write(dateTime);
311             return result.AndThen(WriteLine());
312         }
313         [nodiscard]
314         public Result<bool> Flush()
315         {
316             if (stream == null)
317             {
318                 int errorId = RtmAllocateError("StreamWriter.Flush: stream is null");
319                 SetErrorId(errorId);
320                 return Result<bool>(ErrorId(errorId));
321             }
322             return stream->Flush();
323         }
324         private Stream* stream;
325         private List<UniquePtr<Stream>> streams;
326     }