All pastes #454805 Raw Edit

Unnamed

public text v1 · immutable
·published 2007-04-23 20:41 UTC
rendered paste body
    internal class MyStream : Stream
    {
        #region "constants"

        public int         RECEIVE_BUFFER_SIZE  = 4096;
        public SocketFlags SOCKET_FLAGS         = SocketFlags.None;

        #endregion

        #region events

        public delegate void OnReceiveHandler(int count);
        public event OnReceiveHandler OnReceive;

        #endregion

        #region constructor

        public MyStream(Socket sock)
        {
            m_socket = sock;
            m_recvBuffer = new MemoryStream();
            m_sendBuffer = new MemoryStream();

            _beginReceive();
        }

        #endregion

        #region properties

        public override long Length
        {
            get { return m_recvBuffer.Length; }
        }

        public override bool CanRead
        {
            get { return m_socket.Connected; }
        }
        public override bool CanWrite
        {
            get { return m_socket.Connected; }
        }
        public override bool CanSeek
        {
            get { return true; }
        }

        public override long Position
        {
            get { return 0; }
            set { Seek(value, SeekOrigin.Begin); }
        }

        #endregion

        #region manipulate-methods

        public override void SetLength(long value)
        {
            lock (m_recvBuffer)
                m_recvBuffer.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            lock (m_recvBuffer)
            {
                // read data from buffer + remove it
                m_recvBuffer.Seek(0, SeekOrigin.Begin); // debug
                int read = m_recvBuffer.Read(buffer, offset, count);
                _cutBuffer(ref m_recvBuffer, count);

                return read;
            }
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            lock (m_sendBuffer)
            {
                // put data into buffer
                m_sendBuffer.Seek(0, SeekOrigin.End); // debug
                m_sendBuffer.Write(buffer, offset, count);
            }

            // start asynchronous sending-proccess
            _beginSend();
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            // remove content < pos
            long pos;
            if (origin == SeekOrigin.Begin || origin == SeekOrigin.Current)
                pos = 0 + offset;
            else
                pos = m_recvBuffer.Length - offset;

            lock(m_recvBuffer)
                _cutBuffer(ref m_recvBuffer, pos);

            return 0;
        }

        #endregion

        #region Stream Members

        public override void Flush()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion



        #region Private Methods

        private void _beginReceive()
        {
            // start asynchronous-receiving-proccess
            byte[] buffer = new byte[RECEIVE_BUFFER_SIZE];
            m_socket.BeginReceive(
                buffer,
                0,
                RECEIVE_BUFFER_SIZE,
                SOCKET_FLAGS,
                new AsyncCallback(_onSockReceive),
                buffer);
        }
        private void _beginSend()
        {
            lock(m_sendBuffer)
            {
                // clear buffer + send its content
                byte[] buffer = m_sendBuffer.ToArray();
                m_sendBuffer.SetLength(0);
                m_socket.BeginSend(
                    buffer,
                    0,
                    buffer.Length,
                    SOCKET_FLAGS,
                    new AsyncCallback(_onSockSend),
                    null);
            }
        }

        private void _onSockReceive(IAsyncResult ar)
        {
            // receive data
            int rcvd = m_socket.EndReceive(ar);
            lock (m_recvBuffer)
            {
                /*debug*/m_recvBuffer.Seek(0, SeekOrigin.End);
                m_recvBuffer.Write((byte[]) ar.AsyncState, 0, rcvd);
            }

            // throw OnReceive event
            OnReceive(rcvd);

            // continue receiving..
            _beginReceive();
        }
        private void _onSockSend(IAsyncResult ar)
        {
            // finish asynchronous-sending-proccess
            m_socket.EndSend(ar);
        }

        private static void _cutBuffer(ref MemoryStream buffer, long pos)
        {
            // cut whole content < pos
            int newSize = (int)(buffer.Length - pos);
            byte[] temp = new byte[newSize];
            buffer.Seek(pos, SeekOrigin.Begin);
            buffer.Read(temp, 0, newSize);
            buffer.SetLength(newSize);
            buffer.Seek(0, SeekOrigin.Begin);
            buffer.Write(temp, 0, newSize);
        }

        #endregion

        #region Private Members

        private Socket m_socket;
        private MemoryStream m_recvBuffer;
        private MemoryStream m_sendBuffer;

        #endregion
    }