2 // System.IO.BufferedStream
5 // Matt Kimball (matt@kimball.net)
6 // Ville Palo <vi64pa@kolumbus.fi>
9 using System.Runtime.InteropServices;
12 public sealed class BufferedStream : Stream {
16 int m_buffer_read_ahead;
17 bool m_buffer_reading;
18 private bool disposed = false;
20 public BufferedStream(Stream stream) : this(stream, 4096) {
23 public BufferedStream(Stream stream, int buffer_size) {
26 throw new ArgumentNullException ("stream was null");
28 throw new ArgumentOutOfRangeException ();
31 m_buffer = new byte[buffer_size];
34 public override bool CanRead {
36 return m_stream.CanRead;
40 public override bool CanWrite {
42 return m_stream.CanWrite;
46 public override bool CanSeek {
48 return m_stream.CanSeek;
52 public override long Length {
55 return m_stream.Length;
59 public override long Position {
61 CheckObjectDisposedException ();
62 return m_stream.Position - m_buffer_read_ahead + m_buffer_pos;
67 m_stream.Position = value;
71 public override void Close() {
81 public override void Flush() {
83 CheckObjectDisposedException ();
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([In,Out] 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");