1 // =================================
  2 // Copyright (c) 2024 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public class MemoryWriter : IOBase
 11     {
 12         public MemoryWriter(byte* ptr_long count_) : base()ptr(ptr_)pos(ptr)count(count_)
 13         {
 14         }
 15         [nodiscard]
 16         public Result<bool> Write(bool x)
 17         {
 18             if (Error())
 19             {
 20                 return Result<bool>(ErrorId(GetErrorId()));
 21             }
 22             return Write(cast<byte>(x));
 23         }
 24         [nodiscard]
 25         public Result<bool> Write(byte x)
 26         {
 27             if (Error())
 28             {
 29                 return Result<bool>(ErrorId(GetErrorId()));
 30             }
 31             if (pos - ptr >= count)
 32             {
 33                 int errorId = AllocateError("memory writer: end of space");
 34                 SetErrorId(errorId);
 35                 return Result<bool>(ErrorId(errorId));
 36             }
 37             *pos++ = x;
 38             return Result<bool>(true);
 39         }
 40         [nodiscard]
 41         public Result<bool> Write(sbyte x)
 42         {
 43             if (Error())
 44             {
 45                 return Result<bool>(ErrorId(GetErrorId()));
 46             }
 47             return Write(cast<byte>(x));
 48         }
 49         [nodiscard]
 50         public Result<bool> Write(ushort x)
 51         {
 52             if (Error())
 53             {
 54                 return Result<bool>(ErrorId(GetErrorId()));
 55             }
 56             byte b0 = cast<byte>(x >> 8u);
 57             byte b1 = cast<byte>(x);
 58             auto result = Write(b0);
 59             if (result.Error())
 60             {
 61                 return Result<bool>(ErrorId(result.GetErrorId()));
 62             }
 63             return Write(b1);
 64         }
 65         [nodiscard]
 66         public Result<bool> Write(short x)
 67         {
 68             if (Error())
 69             {
 70                 return Result<bool>(ErrorId(GetErrorId()));
 71             }
 72             return Write(cast<ushort>(x));
 73         }
 74         [nodiscard]
 75         public Result<bool> Write(uint x)
 76         {
 77             if (Error())
 78             {
 79                 return Result<bool>(ErrorId(GetErrorId()));
 80             }
 81             byte b0 = cast<byte>(x >> 24u);
 82             byte b1 = cast<byte>(x >> 16u);
 83             byte b2 = cast<byte>(x >> 8u);
 84             byte b3 = cast<byte>(x);
 85             auto result = Write(b0);
 86             if (result.Error())
 87             {
 88                 return Result<bool>(ErrorId(result.GetErrorId()));
 89             }
 90             result = Write(b1);
 91             if (result.Error())
 92             {
 93                 return Result<bool>(ErrorId(result.GetErrorId()));
 94             }
 95             result = Write(b2);
 96             if (result.Error())
 97             {
 98                 return Result<bool>(ErrorId(result.GetErrorId()));
 99             }
100             return Write(b3);
101         }
102         [nodiscard]
103         public Result<bool> Write(int x)
104         {
105             if (Error())
106             {
107                 return Result<bool>(ErrorId(GetErrorId()));
108             }
109             return Write(cast<uint>(x));
110         }
111         [nodiscard]
112         public Result<bool> Write(ulong x)
113         {
114             if (Error())
115             {
116                 return Result<bool>(ErrorId(GetErrorId()));
117             }
118             byte b0 = cast<byte>(x >> 56u);
119             byte b1 = cast<byte>(x >> 48u);
120             byte b2 = cast<byte>(x >> 40u);
121             byte b3 = cast<byte>(x >> 32u);
122             byte b4 = cast<byte>(x >> 24u);
123             byte b5 = cast<byte>(x >> 16u);
124             byte b6 = cast<byte>(x >> 8u);
125             byte b7 = cast<byte>(x);
126             auto result = Write(b0);
127             if (result.Error())
128             {
129                 return Result<bool>(ErrorId(result.GetErrorId()));
130             }
131             result = Write(b1);
132             if (result.Error())
133             {
134                 return Result<bool>(ErrorId(result.GetErrorId()));
135             }
136             result = Write(b2);
137             if (result.Error())
138             {
139                 return Result<bool>(ErrorId(result.GetErrorId()));
140             }
141             result = Write(b3);
142             if (result.Error())
143             {
144                 return Result<bool>(ErrorId(result.GetErrorId()));
145             }
146             result = Write(b4);
147             if (result.Error())
148             {
149                 return Result<bool>(ErrorId(result.GetErrorId()));
150             }
151             result = Write(b5);
152             if (result.Error())
153             {
154                 return Result<bool>(ErrorId(result.GetErrorId()));
155             }
156             result = Write(b6);
157             if (result.Error())
158             {
159                 return Result<bool>(ErrorId(result.GetErrorId()));
160             }
161             return Write(b7);
162         }
163         [nodiscard]
164         public Result<bool> Write(long x)
165         {
166             if (Error())
167             {
168                 return Result<bool>(ErrorId(GetErrorId()));
169             }
170             return Write(cast<ulong>(x));
171         }
172         [nodiscard]
173         public Result<bool> Write(float x)
174         {
175             if (Error())
176             {
177                 return Result<bool>(ErrorId(GetErrorId()));
178             }
179             uint* u = cast<uint*>(cast<void*>(&x));
180             return Write(*u);
181         }
182         [nodiscard]
183         public Result<bool> Write(double x)
184         {
185             if (Error())
186             {
187                 return Result<bool>(ErrorId(GetErrorId()));
188             }
189             ulong* u = cast<ulong*>(cast<void*>(&x));
190             return Write(*u);
191         }
192         [nodiscard]
193         public Result<bool> Write(char x)
194         {
195             if (Error())
196             {
197                 return Result<bool>(ErrorId(GetErrorId()));
198             }
199             return Write(cast<byte>(x));
200         }
201         [nodiscard]
202         public Result<bool> Write(wchar x)
203         {
204             if (Error())
205             {
206                 return Result<bool>(ErrorId(GetErrorId()));
207             }
208             return Write(cast<ushort>(x));
209         }
210         [nodiscard]
211         public Result<bool> Write(uchar x)
212         {
213             if (Error())
214             {
215                 return Result<bool>(ErrorId(GetErrorId()));
216             }
217             return Write(cast<uint>(x));
218         }
219         [nodiscard]
220         public Result<bool> Write(const Date& date)
221         {
222             if (Error())
223             {
224                 return Result<bool>(ErrorId(GetErrorId()));
225             }
226             auto result = Write(date.Year());
227             if (result.Error())
228             {
229                 return Result<bool>(ErrorId(result.GetErrorId()));
230             }
231             result = Write(cast<sbyte>(date.GetMonth()));
232             if (result.Error())
233             {
234                 return Result<bool>(ErrorId(result.GetErrorId()));
235             }
236             return Write(date.Day());
237         }
238         [nodiscard]
239         public Result<bool> Write(const DateTime& dt)
240         {
241             if (Error())
242             {
243                 return Result<bool>(ErrorId(GetErrorId()));
244             }
245             Date date = dt.GetDate();
246             auto result = Write(date);
247             if (result.Error())
248             {
249                 return Result<bool>(ErrorId(result.GetErrorId()));
250             }
251             return Write(dt.Seconds());
252         }
253         [nodiscard]
254         public Result<bool> Write(const string& s)
255         {
256             if (Error())
257             {
258                 return Result<bool>(ErrorId(GetErrorId()));
259             }
260             for (char c : s)
261             {
262                 auto result = Write(cast<byte>(c));
263                 if (result.Error())
264                 {
265                     return Result<bool>(ErrorId(result.GetErrorId()));
266                 }
267             }
268             return Write(cast<byte>(0u));
269         }
270         [nodiscard]
271         public Result<bool> Write(const Uuid& x)
272         {
273             if (Error())
274             {
275                 return Result<bool>(ErrorId(GetErrorId()));
276             }
277             for (byte b : x)
278             {
279                 auto result = Write(b);
280                 if (result.Error())
281                 {
282                     return Result<bool>(ErrorId(result.GetErrorId()));
283                 }
284             }
285             return Result<bool>(true);
286         }
287         private byte* ptr;
288         private byte* pos;
289         private long count;
290     }