/**
* @file CM_MQ.c
* @brief 实现环形数组的封装
* @author GT-BU
* @date 2021.05.01
* @version V1.0
* @copyright TCT
* @par 修改日志
* <table>
* <tr><th>Date        <th>Version  <th>Author     <th>Description
* <tr><td>2021.05.01  <td>V1.0     <td>GT-BU      <td>创建初始版本
* </table>
*/
#include "CM_RingBuf.h"
#include "CM_Memory.h"

/**
* @brief 环形数组初始化
* @param[inout] pRing 要初始化的环形数组
* @param[in] maxSize 环形数组大小
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CM_RB_Init(INOUT STRU_CM_RING_T* pRing, IN CM_UINT32 maxSize)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    /*- 为环形数组分配内存 */
    pRing->pdata = (CM_INT64 *)CM_Malloc(maxSize * sizeof(CM_INT64));
    /*- 内存分配是否成功 */
    if (NULL != pRing->pdata)
    {
    	ret = CM_Memset((void*)pRing->pdata, (CM_UINT8)0u, maxSize * sizeof(CM_INT64), maxSize * sizeof(CM_INT64));
        /*- 数据结构初始化 */
        pRing->size = maxSize;
        pRing->i = 0u;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 返回执行结果 */
    return ret;
}

/**
* @brief 写环形数组
* @param[in] pRing 要写的环形数组
* @param[in] val 要写的值
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
*/
ENUM_CM_RETURN CM_RB_Write(INOUT STRU_CM_RING_T* pRing, IN CM_INT64 val)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    /*- 指针是否合法 */
    if (NULL != pRing)
    {
        /*- 写入环形数组并更新写索引 */
        pRing->pdata[pRing->i] = val;
        pRing->i = (pRing->i + 1u) % pRing->size;
        ret = ENUM_CM_TRUE;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 返回执行结果 */
    return ret;
}

/**
* @brief 查看环形数组
*
* 仅读取数据，而不弹出.
* @param[in] pMQ 要查看的环形数组
* @param[in] index 要查看的数据索引（从1开始，1为最新数据，size为最老数据）
* @param[out] pVal 要输出的数据缓冲区
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
* @details 本函数不检查环形数组中是否已经写入了足够的数据，需要用户自行检查
*/
ENUM_CM_RETURN CM_RB_Get(IN const STRU_CM_RING_T* pRing, IN CM_UINT16 index, OUT CM_INT64* pVal)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    /*- 输入是否合法 */
    if ((NULL != pRing) && (index <= pRing->size) && (NULL != pVal))
    {
        /*- 获取指定位置的数据值 */
        *pVal = pRing->pdata[((pRing->i + pRing->size) - index) % pRing->size];
        ret = ENUM_CM_TRUE;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 返回执行结果 */
    return ret;
}

/**
* @brief 清零环形数组
* @param[inout] pMQ 要清零的环形数组
* @return 执行结果
* - ENUM_CM_TRUE 成功
* - ENUM_CM_FALSE 失败
* @note 清零环形数组，消息数据缓冲区清零
*/
ENUM_CM_RETURN CM_RB_Clear(INOUT STRU_CM_RING_T* pRing)
{
    /*- 变量初始化 */
    ENUM_CM_RETURN ret = ENUM_CM_FALSE;
    CM_UINT32 i = 0u;
    /*- 输入是否合法 */
    if (NULL != pRing)
    {
        /*- @alias 清零环形数组 */
        for (i = 0u; i < pRing->size; i++)
        {
            pRing->pdata[i] = 0;
        }
        /*- 写索引重置到0 */
        pRing->i = 0u;
        ret = ENUM_CM_TRUE;
    }
    else
	{
		/*- 无处理 */
	}
    /*- 返回执行结果 */
    return ret;
}


