/*
 * 模块名称：Ring Buffer
 * 模块功能：字节环形缓冲区实现，head == tail 为空，head + 1 == tail 为满
 * 适用平台：通用嵌入式平台
 * 作者：王建锋
 * 创建日期：2026-07-19
 * 修改记录：
 *   v1.0  2026-07-19  王建锋  创建初始版本
 */

#include "ringbuf.h"

/*
 * 函数功能：初始化环形缓冲区
 * 入口参数：rb   - 缓冲区控制块指针
 *           pool - 存储池指针
 *           size - 存储池大小（字节）
 * 返 回 值：无
 * 限定条件：rb 和 pool 均为非空指针
 * 函数说明：size 保留一个空位用于区分空/满状态
 */
void ringbuf_init(ringbuf_t *rb, uint8_t *pool, size_t size)
{
    rb->buf  = pool;
    rb->size = size;
    rb->head = 0;
    rb->tail = 0;
}

/*
 * 函数功能：写入数据到环形缓冲区
 * 入口参数：rb   - 缓冲区控制块指针
 *           data - 源数据指针
 *           len  - 待写入长度
 * 返 回 值：实际写入字节数
 * 限定条件：rb 和 data 均为非空指针
 * 函数说明：空间不足时写入能容纳的最大字节数
 */
size_t ringbuf_put(ringbuf_t *rb, const uint8_t *data, size_t len)
{
    size_t cap = 0;
    size_t n = 0;
    size_t i = 0;

    cap = rb->size - 1 - ringbuf_avail(rb);
    n = (len < cap) ? len : cap;

    for (i = 0; i < n; i++) {
        rb->buf[rb->head] = data[i];
        rb->head = (rb->head + 1) % rb->size;
    }

    return n;
}

/*
 * 函数功能：从环形缓冲区读取数据
 * 入口参数：rb   - 缓冲区控制块指针
 *           data - 目标数据指针
 *           len  - 期望读取长度
 * 返 回 值：实际读取字节数
 * 限定条件：rb 和 data 均为非空指针
 * 函数说明：读取后数据从缓冲区移除
 */
size_t ringbuf_get(ringbuf_t *rb, uint8_t *data, size_t len)
{
    size_t n = 0;
    size_t i = 0;

    n = ringbuf_avail(rb);
    n = (n < len) ? n : len;

    for (i = 0; i < n; i++) {
        data[i] = rb->buf[rb->tail];
        rb->tail = (rb->tail + 1) % rb->size;
    }

    return n;
}

/*
 * 函数功能：预读取数据（不移除）
 * 入口参数：rb   - 缓冲区控制块指针
 *           data - 目标数据指针
 *           len  - 期望读取长度
 * 返 回 值：实际可读取字节数
 * 限定条件：rb 和 data 均为非空指针
 * 函数说明：与 ringbuf_get 的区别是不移动 tail 指针
 */
size_t ringbuf_peek(const ringbuf_t *rb, uint8_t *data, size_t len)
{
    size_t n = 0;
    size_t i = 0;
    size_t idx = 0;

    n = ringbuf_avail(rb);
    n = (n < len) ? n : len;

    for (i = 0; i < n; i++) {
        idx = (rb->tail + i) % rb->size;
        data[i] = rb->buf[idx];
    }

    return n;
}

/*
 * 函数功能：获取缓冲区中有效数据长度
 * 入口参数：rb - 缓冲区控制块指针
 * 返 回 值：有效数据字节数
 * 限定条件：rb 为非空指针
 */
size_t ringbuf_avail(const ringbuf_t *rb)
{
    if (rb->head >= rb->tail) {
        return rb->head - rb->tail;
    }
    return rb->size - rb->tail + rb->head;
}

/*
 * 函数功能：获取缓冲区剩余空间
 * 入口参数：rb - 缓冲区控制块指针
 * 返 回 值：剩余空间字节数（保留一个空位）
 * 限定条件：rb 为非空指针
 */
size_t ringbuf_space(const ringbuf_t *rb)
{
    return rb->size - 1 - ringbuf_avail(rb);
}

/*
 * 函数功能：判断缓冲区是否为空
 * 入口参数：rb - 缓冲区控制块指针
 * 返 回 值：1 - 空，0 - 非空
 * 限定条件：rb 为非空指针
 */
int ringbuf_is_empty(const ringbuf_t *rb)
{
    return (rb->head == rb->tail) ? 1 : 0;
}

/*
 * 函数功能：判断缓冲区是否为满
 * 入口参数：rb - 缓冲区控制块指针
 * 返 回 值：1 - 满，0 - 非满
 * 限定条件：rb 为非空指针
 */
int ringbuf_is_full(const ringbuf_t *rb)
{
    return (ringbuf_avail(rb) == rb->size - 1) ? 1 : 0;
}

/*
 * 函数功能：重置缓冲区
 * 入口参数：rb - 缓冲区控制块指针
 * 返 回 值：无
 * 限定条件：rb 为非空指针
 */
void ringbuf_reset(ringbuf_t *rb)
{
    rb->head = 0;
    rb->tail = 0;
}
