2 // System.IO.BufferedStream
5 // Matt Kimball (matt@kimball.net)
6 // Ville Palo <vi64pa@kolumbus.fi>
11 public sealed class BufferedStream : Stream {
15 int m_buffer_read_ahead;
16 bool m_buffer_reading;
17 private bool disposed = false;
19 public BufferedStream(Stream stream) : this(stream, 4096) {
22 public BufferedStream(Stream stream, int buffer_size) {
25 throw new ArgumentNullException ("stream was null");
27 throw new ArgumentOutOfRangeException ();
29 // There are stream classes that don't support Positioning.
31 // if stream is closed this throws an exception
33 long l = stream.Position;
37 m_buffer = new byte[buffer_size];
40 public override bool CanRead {
42 return m_stream.CanRead;
46 public override bool CanWrite {
48 return m_stream.CanWrite;
52 public override bool CanSeek {
54 return m_stream.CanSeek;
58 public override long Length {
61 return m_stream.Length;
65 public override long Position {
67 return m_stream.Position - m_buffer_read_ahead + m_buffer_pos;
72 m_stream.Position = value;
76 public override void Close() {
83 public override void Flush() {
85 if (m_buffer_reading) {
87 m_stream.Position = Position;
88 } else if (m_buffer_pos > 0) {
89 m_stream.Write(m_buffer, 0, m_buffer_pos);
92 m_buffer_read_ahead = 0;
96 public override long Seek(long offset, SeekOrigin origin) {
98 return m_stream.Seek(offset, origin);
101 public override void SetLength(long value) {
102 m_stream.SetLength(value);
105 public override int ReadByte() {
107 CheckObjectDisposedException ();
109 byte[] b = new byte[1];
111 if (Read(b, 0, 1) == 1) {
118 public override void WriteByte(byte value) {
120 CheckObjectDisposedException ();
121 byte[] b = new byte[1];
127 public override int Read(byte[] array, int offset, int count) {
129 CheckObjectDisposedException ();
131 if (array.Length < offset + count)
132 throw new ArgumentException ();
134 throw new ArgumentOutOfRangeException ("Offset was negative value.");
136 if (!m_buffer_reading) {
138 m_buffer_reading = true;
141 if (count <= m_buffer_read_ahead - m_buffer_pos) {
142 Array.Copy(m_buffer, m_buffer_pos, array, offset, count);
144 m_buffer_pos += count;
145 if (m_buffer_pos == m_buffer_read_ahead) {
147 m_buffer_read_ahead = 0;
153 int ret = m_buffer_read_ahead - m_buffer_pos;
154 Array.Copy(m_buffer, m_buffer_pos, array, offset, ret);
156 m_buffer_read_ahead = 0;
160 if (count >= m_buffer.Length) {
161 ret += m_stream.Read(array, offset, count);
163 m_buffer_read_ahead = m_stream.Read(m_buffer, 0, m_buffer.Length);
165 if (count < m_buffer_read_ahead) {
166 Array.Copy(m_buffer, 0, array, offset, count);
167 m_buffer_pos = count;
170 Array.Copy(m_buffer, 0, array, offset, m_buffer_read_ahead);
171 ret += m_buffer_read_ahead;
172 m_buffer_read_ahead = 0;
179 public override void Write(byte[] array, int offset, int count) {
181 CheckObjectDisposedException ();
183 if (!m_stream.CanRead)
184 throw new NotSupportedException ();
186 throw new ArgumentOutOfRangeException ();
188 if (m_buffer_reading) {
190 m_buffer_reading = false;
193 if (m_buffer_pos + count >= m_buffer.Length) {
195 m_stream.Write(array, offset, count);
197 Array.Copy(array, offset, m_buffer, m_buffer_pos, count);
198 m_buffer_pos += count;
202 private void CheckObjectDisposedException ()
205 throw new ObjectDisposedException ("BufferedStream", "Stream is closed");