1 // =================================
  2 // Copyright (c) 2025 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public const int stdin = 0;
 11     public const int stdout = 1;
 12     public const int stderr = 2;
 13 
 14     public bool IsConsoleHandle(int handle)
 15     {
 16         return RtmIsConsoleHandle(handle);
 17     }
 18 
 19     public enum OpenMode : byte
 20     {
 21         none = 0u
 22         read = 1u << 0u
 23         write = 1u << 1u
 24         append = 1u << 2u
 25         binary = 1u << 3u
 26     }
 27 
 28     public class FileStream : Stream
 29     {
 30         public FileStream(int handle) : file(null)
 31         {
 32             int errorId = 0;
 33             file = RtmOpenStdFile(handleerrorId);
 34             if (file == null)
 35             {
 36                 SetErrorId(errorId);
 37             }
 38         }
 39         public FileStream(const string& filePathOpenMode openMode) : file(null)
 40         {
 41             auto result = Open(filePathopenMode);
 42         }
 43         suppress FileStream(const FileStream&);
 44         suppress void operator=(const FileStream&);
 45         public FileStream(FileStream&& that) : file(that.file)
 46         {
 47             that.file = null;
 48         }
 49         public default void operator=(FileStream&&);
 50         public override ~FileStream()
 51         {
 52             if (file != null)
 53             {
 54                 int errorId = 0;
 55                 RtmDisposeFile(fileerrorId);
 56             }
 57         }
 58         public inline bool IsOpen() const
 59         {
 60             return file != null;
 61         }
 62         [nodiscard]
 63         public Result<bool> Open(const string& filePathOpenMode openMode)
 64         {
 65             Close();
 66             int errorId = 0;
 67             file = RtmOpenFile(filePath.Chars()openModeerrorId);
 68             if (file == null)
 69             {
 70                 SetErrorId(errorId);
 71                 return Result<bool>(ErrorId(errorId));
 72             }
 73             return Result<bool>(true);
 74         }
 75         public Result<bool> Close()
 76         {
 77             if (file != null)
 78             {
 79                 int errorId = 0;
 80                 if (!RtmClose(fileerrorId))
 81                 {
 82                     SetErrorId(errorId);
 83                     return Result<bool>(ErrorId(errorId));
 84                 }
 85                 file = null;
 86             }
 87             return Result<bool>(true);
 88         }
 89         [nodiscard]
 90         public override Result<int> ReadByte()
 91         {
 92             int errorId = 0;
 93             int result = RtmReadByte(fileerrorId);
 94             if (errorId != 0)
 95             {
 96                 SetErrorId(errorId);
 97                 return Result<int>(ErrorId(errorId));
 98             }
 99             if (result == -1)
100             {
101                 if (RtmEof(file))
102                 {
103                     return Result<int>(-1);
104                 }
105                 else
106                 {
107                     int errorId = 0;
108                     if (RtmGetFileError(fileerrorId))
109                     {
110                         SetErrorId(errorId);
111                         return Result<int>(ErrorId(errorId));
112                     }
113                 }
114             }
115             return result;
116         }
117         [nodiscard]
118         public override Result<long> Read(byte* bufferlong count)
119         {
120             if (count < 0)
121             {
122                 int errorId = RtmAllocateError("FileStream.Read: count less than zero");
123                 SetErrorId(errorId);
124                 return Result<long>(ErrorId(errorId));
125             }
126             int errorId = 0;
127             long result = RtmRead(filebuffercounterrorId);
128             if (result == -1)
129             {
130                 SetErrorId(errorId);
131                 return Result<long>(ErrorId(errorId));
132             }
133             return Result<long>(result);
134         }
135         [nodiscard]
136         public override Result<bool> Write(byte x)
137         {
138             int errorId = 0;
139             if (!RtmWriteByte(filexerrorId))
140             {
141                 SetErrorId(errorId);
142                 return Result<bool>(ErrorId(errorId));
143             }
144             return Result<bool>(true);
145         }
146         [nodiscard]
147         public override Result<bool> Write(byte* bufferlong count)
148         {
149             if (count < 0)
150             {
151                 int errorId = RtmAllocateError("FileStream.Write: count less than zero");
152                 SetErrorId(errorId);
153                 return Result<bool>(ErrorId(errorId));
154             }
155             int errorId = 0;
156             long result = RtmWrite(filebuffercounterrorId);
157             if (result == -1)
158             {
159                 SetErrorId(errorId);
160                 return Result<bool>(ErrorId(errorId));
161             }
162             return Result<bool>(true);
163         }
164         [nodiscard]
165         public override Result<bool> Seek(long posOrigin origin)
166         {
167             int errorId = 0;
168             if (!RtmSeek(fileposoriginerrorId))
169             {
170                 SetErrorId(errorId);
171                 return Result<bool>(ErrorId(errorId));
172             }
173             return Result<bool>(true);
174         }
175         [nodiscard]
176         public override Result<long> Tell()
177         {
178             int errorId = 0;
179             long result = RtmTell(fileerrorId);
180             if (result == -1)
181             {
182                 SetErrorId(errorId);
183                 return Result<long>(ErrorId(errorId));
184             }
185             return Result<long>(result);
186         }
187         [nodiscard]
188         public override Result<bool> Flush()
189         {
190             int errorId = 0;
191             if (!RtmFlush(fileerrorId))
192             {
193                 SetErrorId(errorId);
194                 return Result<bool>(ErrorId(errorId));
195             }
196             return Result<bool>(true);
197         }
198         private void* file;
199     }
200 }
201 
202 namespace System
203 {
204     public class Endl
205     {
206         public Endl()
207         {
208         }
209     }
210 
211     public Endl endl()
212     {
213         return Endl();
214     }