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 enum Origin : byte
11     {
12         seekSetseekCurseekEnd
13     }
14 
15     public abstract class Stream : IOBase
16     {
17         public Stream() : base() {}
18         suppress Stream(const Stream&);
19         suppress void operator=(const Stream&);
20         public default Stream(Stream&&);
21         public default void operator=(Stream&&);
22         [nodiscard]
23         public abstract Result<int> ReadByte();
24         [nodiscard]
25         public abstract Result<long> Read(byte* buflong count);
26         [nodiscard]
27         public abstract Result<bool> Write(byte x);
28         [nodiscard]
29         public abstract Result<bool> Write(byte* buflong count);
30         public virtual Result<bool> Flush()
31         {
32             return Result<bool>(true);
33         }
34         [nodiscard]
35         public virtual Result<bool> Seek(long posOrigin origin)
36         {
37             string streamClassName = typename(*this);
38             string errorMessage = streamClassName + " stream does not support seek";
39             int errorId = RtmAllocateError(errorMessage.Chars());
40             SetErrorId(errorId);
41             return Result<bool>(ErrorId(errorId));
42         }
43         [nodiscard]
44         public virtual Result<long> Tell()
45         {
46             string streamClassName = typename(*this);
47             string errorMessage = streamClassName + " stream does not support tell";
48             int errorId = RtmAllocateError(errorMessage.Chars());
49             SetErrorId(errorId);
50             return Result<long>(ErrorId(errorId));
51         }
52         [nodiscard]
53         public Result<bool> CopyTo(Stream& destination)
54         {
55             return this->CopyTo(destination16384);
56         }
57         [nodiscard]
58         public Result<bool> CopyTo(Stream& destinationlong bufferSize)
59         {
60             if (bufferSize <= 0)
61             {
62                 int errorId = AllocateError("invalid buffer size");
63                 return Result<bool>(ErrorId(errorId));
64             }
65             IOBuffer buffer(bufferSize);
66             auto readResult = Read(cast<byte*>(buffer.Mem())bufferSize);
67             if (readResult.Error())
68             {
69                 return Result<bool>(ErrorId(readResult.GetErrorId()));
70             }
71             long bytesRead = readResult.Value();
72             while (bytesRead > 0)
73             {
74                 auto writeResult = destination.Write(cast<byte*>(buffer.Mem())bytesRead);
75                 if (writeResult.Error())
76                 {
77                     return Result<bool>(ErrorId(writeResult.GetErrorId()));
78                 }
79                 readResult = Read(cast<byte*>(buffer.Mem())bufferSize);
80                 if (readResult.Error())
81                 {
82                     return Result<bool>(ErrorId(readResult.GetErrorId()));
83                 }
84                 bytesRead = readResult.Value();
85             }
86             return Result<bool>(true);
87         }
88     }