1 // =================================
  2 // Copyright (c) 2022 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 using System;
  7 
  8 namespace System.IO
  9 {
 10     public class BufferedStream : Stream
 11     {
 12         public nothrow BufferedStream(const SharedPtr<Stream>& baseStream_) : this(baseStream_4096)
 13         {
 14         }
 15         public nothrow BufferedStream(const SharedPtr<Stream>& baseStream_long bufferSize_) : 
 16             baseStream(baseStream_)buffer(bufferSize_)pos(buffer.Size())bytesAvailable(0)end(0)
 17         {
 18         }
 19         suppress BufferedStream(const BufferedStream&);
 20         suppress void operator=(const BufferedStream&);
 21         public override ~BufferedStream()
 22         {
 23             try
 24             {
 25                 if (!baseStream.IsNull())
 26                 {
 27                     Flush();
 28                 }
 29             }
 30             catch (const Exception&)
 31             {
 32             }
 33         }
 34         public override int ReadByte()
 35         {
 36             Flush();
 37             if (bytesAvailable == 0)
 38             {
 39                 FillBuf();
 40                 if (bytesAvailable == 0)
 41                 {
 42                     return -1;
 43                 }
 44             }
 45             byte value = buffer[pos++];
 46             --bytesAvailable;
 47             return value;
 48         }
 49         public override long Read(byte* buflong count)
 50         {
 51             if (count < 0)
 52             {
 53                 ThrowInvalidParameterException();
 54             }
 55             Flush();
 56             if (bytesAvailable == 0)
 57             {
 58                 FillBuf();
 59             }
 60             long bytesRead = 0;
 61             long n = Min(bytesAvailablecount);
 62             for (long i = 0; i < n; ++i;)
 63             {
 64                 buf[i] = buffer[pos++];
 65                 ++bytesRead;
 66                 --bytesAvailable;
 67             }
 68             return bytesRead;
 69         }
 70         public override long Write(byte x)
 71         {
 72             if (end >= buffer.Size())
 73             {
 74                 Flush();
 75             }
 76             buffer[end++] = x;
 77             return 1;
 78         }
 79         public override long Write(byte* buflong count)
 80         {
 81             if (count < 0)
 82             {
 83                 ThrowInvalidParameterException();
 84             }
 85             for (long i = 0; i < count; ++i;)
 86             {
 87                 Write(buf[i]);
 88             }
 89             return count;
 90         }
 91         public override void Flush()
 92         {
 93             if (end != 0)
 94             {
 95                 baseStream->Write(buffer.Mem()end);
 96                 end = 0;
 97             }
 98         }
 99         public override long Seek(long posOrigin origin)
100         {
101             Flush();
102             bytesAvailable = 0;
103             return baseStream->Seek(posorigin);
104         }
105         public override long Tell()
106         {
107             Flush();
108             return baseStream->Tell() - bytesAvailable;
109         }
110         public nothrow const SharedPtr<Stream>& BaseStream()
111         {
112             return baseStream;
113         }
114         public override bool IsHostTextFile() const
115         {
116             return baseStream->IsHostTextFile();
117         }
118         public override bool IsConsole() const
119         {
120             return baseStream->IsConsole();
121         }
122         private void FillBuf()
123         {
124             bytesAvailable = baseStream->Read(buffer.Mem()buffer.Size());
125             pos = 0;
126         }
127         private SharedPtr<Stream> baseStream;
128         private Buffer buffer;
129         private long pos;
130         private long bytesAvailable;
131         private long end;
132     }
133 }