using System.Text; using System.Diagnostics; namespace System.IO { public class StreamWriter { Stream mStream ~ if (mOwnsStream) delete _; public bool mOwnsStream; public Encoding mEncoding; public bool AutoFlush; public this() { } public this(Stream stream, Encoding encoding, int32 bufferSize, bool ownsStream = false) { Debug.Assert(encoding != null); mStream = stream; mEncoding = encoding; mOwnsStream = ownsStream; } public Result Create(StringView fileName) { Debug.Assert(mStream == null); var fileStream = new FileStream(); mStream = fileStream; mEncoding = .UTF8; mOwnsStream = true; if (fileStream.Open(fileName, FileMode.Create, FileAccess.Write, FileShare.ReadWrite) case .Err(let err)) return .Err(err); return .Ok; } public Result Write(Span data) { var spanLeft = data; while (!spanLeft.IsEmpty) { int bytesWritten = Try!(mStream.TryWrite(spanLeft)); spanLeft.Adjust(bytesWritten); } if (AutoFlush) Flush(); return .Ok; } public Result Write(StringView str) { var curSpan = str; Span outSpan = scope uint8[4096]; while (!curSpan.IsEmpty) { switch (mEncoding.Encode(curSpan, outSpan)) { case .Ok(let encodedBytes): Try!(Write(Span(outSpan.Ptr, encodedBytes))); return .Ok; case .Err(let err): switch (err) { case .PartialEncode(int inChars, int encodedBytes): Try!(Write(Span(outSpan.Ptr, encodedBytes))); curSpan.Adjust(inChars); } } } return .Ok; } public Result WriteLine() { return Write("\n"); } public Result WriteLine(StringView str) { Try!(Write(str)); return Write("\n"); } public Result Write(StringView fmt, params Object[] args) { return Write(scope String()..AppendF(fmt, params args)); } public Result WriteLine(StringView fmt, params Object[] args) { Try!(Write(scope String()..AppendF(fmt, params args))); return Write("\n"); } public void Flush() { mStream.Flush(); } } }