1
2
3
4
5
6 using System;
7
8 namespace System.IO
9 {
10 public class IOBuffer
11 {
12 public nothrow IOBuffer(long size_) : size(size_), mem(null)
13 {
14 #if (MEM_DEBUG)
15 mem = MemAlloc(size, typename(*this));
16 #else
17 mem = MemAlloc(size);
18 #endif
19 }
20 suppress IOBuffer(const IOBuffer&);
21 suppress void operator=(const IOBuffer&);
22 public nothrow IOBuffer(IOBuffer&& that) : size(that.size), mem(that.mem)
23 {
24 that.size = 0;
25 that.mem = null;
26 }
27 public default nothrow void operator=(IOBuffer&& that);
28 public ~IOBuffer()
29 {
30 if (mem != null)
31 {
32 MemFree(mem);
33 }
34 }
35 public inline nothrow long Size() const
36 {
37 return size;
38 }
39 public inline nothrow void* Mem() const
40 {
41 return mem;
42 }
43 public inline byte operator[](long index) const
44 {
45 if (index < 0 || index >= size)
46 {
47 ThrowIndexOutOfBoundsException();
48 }
49 return cast<byte*>(mem)[index];
50 }
51 public inline nothrow byte& operator[](long index)
52 {
53 return cast<byte*>(mem)[index];
54 }
55 private long size;
56 private void* mem;
57 }
58
59 public class BufferedByteStream : ByteStream
60 {
61 public nothrow BufferedByteStream(const SharedPtr<ByteStream>& baseStream_) : this(baseStream_, 4096)
62 {
63 }
64 public nothrow BufferedByteStream(const SharedPtr<ByteStream>& baseStream_, long bufferSize_) :
65 baseStream(baseStream_), buffer(bufferSize_), pos(buffer.Size()), bytesAvailable(0), end(0)
66 {
67 }
68 suppress BufferedByteStream(const BufferedByteStream&);
69 suppress void operator=(const BufferedByteStream&);
70 public override ~BufferedByteStream()
71 {
72 try
73 {
74 if (!baseStream.IsNull())
75 {
76 Flush();
77 }
78 }
79 catch (const Exception&)
80 {
81 }
82 }
83 public override int ReadByte()
84 {
85 Flush();
86 if (bytesAvailable == 0)
87 {
88 FillBuf();
89 if (bytesAvailable == 0)
90 {
91 return -1;
92 }
93 }
94 byte value = buffer[pos++];
95 --bytesAvailable;
96 return value;
97 }
98 public override long Read(byte* buf, long count)
99 {
100 if (count < 0)
101 {
102 ThrowInvalidParameterException();
103 }
104 Flush();
105 if (bytesAvailable == 0)
106 {
107 FillBuf();
108 }
109 long bytesRead = 0;
110 long n = Min(bytesAvailable, count);
111 for (long i = 0; i < n; ++i;)
112 {
113 buf[i] = buffer[pos++];
114 ++bytesRead;
115 --bytesAvailable;
116 }
117 return bytesRead;
118 }
119 public override void Write(byte x)
120 {
121 if (end >= buffer.Size())
122 {
123 Flush();
124 }
125 buffer[end++] = x;
126 }
127 public override void Write(byte* buf, long count)
128 {
129 if (count < 0)
130 {
131 ThrowInvalidParameterException();
132 }
133 for (long i = 0; i < count; ++i;)
134 {
135 Write(buf[i]);
136 }
137 }
138 public override void Flush()
139 {
140 if (end != 0)
141 {
142 baseStream->Write(cast<byte*>(buffer.Mem()), end);
143 baseStream->Flush();
144 end = 0;
145 }
146 }
147 public override void Seek(long pos, Origin origin)
148 {
149 Flush();
150 bytesAvailable = 0;
151 baseStream->Seek(pos, origin);
152 }
153 public override long Tell()
154 {
155 Flush();
156 return baseStream->Tell() - bytesAvailable;
157 }
158 public nothrow const SharedPtr<ByteStream>& ContainedStream()
159 {
160 return baseStream;
161 }
162 private void FillBuf()
163 {
164 bytesAvailable = baseStream->Read(cast<byte*>(buffer.Mem()), buffer.Size());
165 pos = 0;
166 }
167 private SharedPtr<ByteStream> baseStream;
168 private IOBuffer buffer;
169 private long pos;
170 private long bytesAvailable;
171 private long end;
172 }
173 }