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 // if stream is closed this throws an exception FIXME: better way?
31 long l = stream.Position;
35 m_buffer = new byte[buffer_size];
38 public override bool CanRead {
40 return m_stream.CanRead;
44 public override bool CanWrite {
46 return m_stream.CanWrite;
50 public override bool CanSeek {
52 return m_stream.CanSeek;
56 public override long Length {
59 return m_stream.Length;
63 public override long Position {
65 return m_stream.Position - m_buffer_read_ahead + m_buffer_pos;
70 m_stream.Position = value;
74 public override void Close() {
81 public override void Flush() {
83 if (m_buffer_reading) {
85 m_stream.Position = Position;
86 } else if (m_buffer_pos > 0) {
87 m_stream.Write(m_buffer, 0, m_buffer_pos);
90 m_buffer_read_ahead = 0;
94 public override long Seek(long offset, SeekOrigin origin) {
96 return m_stream.Seek(offset, origin);
99 public override void SetLength(long value) {
100 m_stream.SetLength(value);
103 public override int ReadByte() {
105 CheckObjectDisposedException ();
107 byte[] b = new byte[1];
109 if (Read(b, 0, 1) == 1) {
116 public override void WriteByte(byte value) {
118 CheckObjectDisposedException ();
119 byte[] b = new byte[1];
125 public override int Read(byte[] array, int offset, int count) {
127 CheckObjectDisposedException ();
129 if (array.Length < offset + count)
130 throw new ArgumentException ();
132 throw new ArgumentOutOfRangeException ("Offset was negative value.");
134 if (!m_buffer_reading) {
136 m_buffer_reading = true;
139 if (count <= m_buffer_read_ahead - m_buffer_pos) {
140 Array.Copy(m_buffer, m_buffer_pos, array, offset, count);
142 m_buffer_pos += count;
143 if (m_buffer_pos == m_buffer_read_ahead) {
145 m_buffer_read_ahead = 0;
151 int ret = m_buffer_read_ahead - m_buffer_pos;
152 Array.Copy(m_buffer, m_buffer_pos, array, offset, ret);
154 m_buffer_read_ahead = 0;
158 if (count >= m_buffer.Length) {
159 ret += m_stream.Read(array, offset, count);
161 m_buffer_read_ahead = m_stream.Read(m_buffer, 0, m_buffer.Length);
163 if (count < m_buffer_read_ahead) {
164 Array.Copy(m_buffer, 0, array, offset, count);
165 m_buffer_pos = count;
168 Array.Copy(m_buffer, 0, array, offset, m_buffer_read_ahead);
169 ret += m_buffer_read_ahead;
170 m_buffer_read_ahead = 0;
177 public override void Write(byte[] array, int offset, int count) {
179 CheckObjectDisposedException ();
181 if (!m_stream.CanRead)
182 throw new NotSupportedException ();
184 throw new ArgumentOutOfRangeException ();
186 if (m_buffer_reading) {
188 m_buffer_reading = false;
191 if (m_buffer_pos + count >= m_buffer.Length) {
193 m_stream.Write(array, offset, count);
195 Array.Copy(array, offset, m_buffer, m_buffer_pos, count);
196 m_buffer_pos += count;
200 private void CheckObjectDisposedException ()
203 throw new ObjectDisposedException ("BufferedStream", "Stream is closed");