/*----------------------------------------------------------------------------------------------
 
       Copyright (C) DHCC 版权所有

       系统名:
       类  名:  BufferManager
       概  要: 
       创建者:  Hu Ha
       创建日:  01/18/2010 17:13:01
       履  历:    No.        日期           Ver.No        修改人             描述																																																																										

------------------------------------------------------------------------------------------------*/

using System;
using System.Collections.Generic;
using System.Text;

namespace TellerSystem.Communication.SocketListener
{
    /// <summary>
    /// 提供接收和发送缓冲区的管理
    /// </summary>
    public sealed class BufferManager
    {
        private byte[] m_receiveBuffer;
        private byte[] m_sendBuffer;

        private int m_maxRequest;
        private int m_receiveBufferSize;
        private int m_sendBufferSize;

        private int m_bufferBlockIndex;
        private Stack<int> m_bufferBlockIndexStack;

        private static object Locker = new object();

        /// <summary>
        /// Initializes a new instance of the <see cref="BufferManager"/> class.
        /// </summary>
        /// <param name="maxRequest">The max request.</param>
        /// <param name="receivevBufferSize">Size of the receivev buffer.</param>
        /// <param name="sendBufferSize">Size of the send buffer.</param>
        public BufferManager(int maxRequest, int receivevBufferSize, int sendBufferSize)
        {
            m_maxRequest = maxRequest;
            m_receiveBufferSize = receivevBufferSize;
            m_sendBufferSize = sendBufferSize;

            m_bufferBlockIndex = 0;
            m_bufferBlockIndexStack = new Stack<int>(maxRequest);

            m_receiveBuffer = new byte[m_receiveBufferSize * m_maxRequest];
            m_sendBuffer = new byte[m_sendBufferSize * m_maxRequest];
        }

        /// <summary>
        /// 接收缓冲区总长度
        /// </summary>
        public int ReceiveBufferSize
        {
            get { return m_receiveBufferSize; }
        }

        /// <summary>
        /// 发送缓冲区总长度
        /// </summary>
        public int SendBufferSize
        {
            get { return m_sendBufferSize; }
        }

        /// <summary>
        /// 接收缓冲区
        /// </summary>
        public byte[] ReceiveBuffer
        {
            get { return m_receiveBuffer; }
        }

        /// <summary>
        /// 发送缓冲区
        /// </summary>
        public byte[] SendBuffer
        {
            get { return m_sendBuffer; }
        }

        /// <summary>
        /// 释放缓冲区索引
        /// </summary>
        /// <param name="bufferBlockIndex"></param>
        public void FreeBufferBlockIndex(int bufferBlockIndex)
        {
            if (bufferBlockIndex >= this.m_maxRequest || bufferBlockIndex < 0)
            {
                return;
            }

            lock (Locker)
            {
                if (this.m_bufferBlockIndexStack.Contains(bufferBlockIndex))
                    return;

                m_bufferBlockIndexStack.Push(bufferBlockIndex);
            }
        }

        /// <summary>
        /// 获取缓冲区空闲的索引
        /// </summary>
        /// <returns></returns>
        public int GetBufferBlockIndex()
        {
            lock (Locker)
            {
                int blockIndex = -1;

                // 有用过释放的缓冲块
                if (m_bufferBlockIndexStack.Count > 0)
                {
                    blockIndex = m_bufferBlockIndexStack.Pop();
                }
                else
                {
                    // 有未用缓冲区块
                    if (m_bufferBlockIndex < m_maxRequest)
                    {
                        blockIndex = m_bufferBlockIndex++;
                    }
                }

                return blockIndex;
            }
        }

        /// <summary>
        /// 获取接收缓冲区偏移量
        /// </summary>
        /// <param name="bufferBlockIndex">此接收缓冲区在整个缓冲区的索引</param>
        /// <returns>接收缓冲区偏移量</returns>
        public int GetReceiveBufferOffset(int bufferBlockIndex)
        {
            if (bufferBlockIndex >= this.m_maxRequest)
            {
                throw new ArgumentException(string.Format("索引超出最大请求数:{0}", this.m_maxRequest.ToString()));
            }

            if (bufferBlockIndex < 0)
            {
                return 0;
            }

            return bufferBlockIndex * m_receiveBufferSize;
        }

        /// <summary>
        /// 获取发送缓冲区偏移量
        /// </summary>
        /// <param name="bufferBlockIndex">此发送缓冲区在整个缓冲区的索引</param>
        /// <returns>发送缓冲区偏移量</returns>
        public int GetSendBufferOffset(int bufferBlockIndex)
        {
            if (bufferBlockIndex >= this.m_maxRequest)
            {
                throw new ArgumentException(string.Format("索引超出最大请求数:{0}", this.m_maxRequest.ToString()));
            }

            if (bufferBlockIndex < 0)
            {
                return 0;
            }

            return bufferBlockIndex * m_sendBufferSize;
        }

        /// <summary>
        /// 清理缓冲区
        /// </summary>
        public void Clear()
        {
            m_bufferBlockIndexStack.Clear();
            m_receiveBuffer = null;
            m_sendBuffer = null;
        }
    }
}