#include "sr_ringbuff.h"
#include <stdio.h>
#include <string.h>

#define min(a,b) ( (a) < (b) )? (a):(b)   

//Ringbuff初始化
int SR_RbInit(SR_RINGBUFF_T *rb,uint8_t *buff,uint16_t size)
{
  rb->head=0;
  rb->tail=0;
  rb->curLen=0;
  rb->totalSize=size;
  rb->pBuff = buff;

#ifdef SR_USE_OS  
  //创建互斥量
  rb->mutex = SR_OsMutexCreate();
  return (rb->mutex)? SR_OK:SR_FAIL;
#else
  return SR_OK;
#endif
}

//ringbuff创建
SR_RINGBUFF_T *SR_RbCreate(uint16_t size)
{
  SR_RINGBUFF_T *rb = SR_NULL;
  if(!size) return SR_NULL;

  //包含柔性数组在内一起分配空间
  rb = (SR_RINGBUFF_T *)SR_OsMalloc(sizeof(SR_RINGBUFF_T)+size);
  if(!rb) return SR_NULL;

#ifdef SR_USE_OS  
  //创建互斥量
  rb->mutex = SR_OsMutexCreate();
  if(!rb->mutex) 
  {
      SR_OsFree(rb);
      return SR_NULL;
  }
#endif

  //初始化
  rb->head=0;
  rb->tail=0;
  rb->curLen=0;
  rb->totalSize=size;
  rb->pBuff = rb->pDynBuff;

  return rb;
}

//ringbuff销毁
int SR_RbDestroy(SR_RINGBUFF_T *rb)
{
#ifdef SR_USE_OS  
  SR_OsMutexDelete(rb->mutex);    //销毁互斥量
#endif
  SR_OsFree(rb);  //释放rb内存
  return 0;
}

//写一个字节
int SR_RbWriteByte(SR_RINGBUFF_T *rb,uint8_t data)
{
  int ret=1;

#ifdef SR_USE_OS  
  SR_OsMutexTake(rb->mutex,OS_WAIT_FOREVER);  //上锁
#endif

  if(rb->curLen>=rb->totalSize)  //buff已满
  {   
      ret = 0; 
      goto _end;
  }

  rb->pBuff[rb->tail]=data;
  rb->tail=(rb->tail+1)%rb->totalSize; //防止非法越界
  rb->curLen++;

_end:
#ifdef SR_USE_OS  
	SR_OsMutexRelease(rb->mutex);  //关锁
#endif

  return ret; 
}

//写多个字节
int SR_RbWriteLen(SR_RINGBUFF_T *rb,uint8_t *data,uint16_t dLen)
{
  int ret=0;

#ifdef SR_USE_OS  
    SR_OsMutexTake(rb->mutex,OS_WAIT_FOREVER);  //上锁
#endif

  if(rb->curLen>=rb->totalSize)  //buff已满
  {    
      goto _end;
  }

  //计算可写入的长度
  ret =  min(dLen,(rb->totalSize-rb->curLen));

  //写入数据
  for(int i=0;i<ret;i++)
  {
    rb->pBuff[rb->tail]=data[i];
    rb->tail=(rb->tail+1)%rb->totalSize; //防止非法越界
    rb->curLen++;
  }

_end:
#ifdef SR_USE_OS  
  	SR_OsMutexRelease(rb->mutex);  //关锁
#endif

  return ret; 
}

//读一个字节
int SR_RbReadByte(SR_RINGBUFF_T *rb,uint8_t *rData)
{
  int ret=1;

#ifdef SR_USE_OS  
  SR_OsMutexTake(rb->mutex,OS_WAIT_FOREVER);  //上锁
#endif

  if(rb->curLen==0)  
  {
    ret = 0; //buff为空
    goto _end;
  }
  
  *rData=rb->pBuff[rb->head];
  rb->head=(rb->head+1)%rb->totalSize;
  rb->curLen--;

_end:
#ifdef SR_USE_OS
  SR_OsMutexRelease(rb->mutex);  //关锁
#endif

  return ret;
}


//读多个字节
int SR_RbReadLen(SR_RINGBUFF_T *rb,uint8_t *rData,uint16_t dLen)
{
  int ret=0;

#ifdef SR_USE_OS  
  SR_OsMutexTake(rb->mutex,OS_WAIT_FOREVER);  //上锁
#endif

  if(rb->curLen==0)  //buff为空
  {
    goto _end;
  }

  //计算可读取的长度
  ret =  min(dLen,rb->curLen);
  
  for(int i=0;i<ret;i++)
  {
    rData[i]=rb->pBuff[rb->head];
    rb->head=(rb->head+1)%rb->totalSize;
    rb->curLen--;
  }

_end:
#ifdef SR_USE_OS
  SR_OsMutexRelease(rb->mutex);  //关锁
#endif

  return ret;
}

//获取可用数据长度
uint16_t SR_RbGetValidLen(SR_RINGBUFF_T *rb)
{
  return rb->curLen;
}

//ringbuff清空
void SR_RbClear(SR_RINGBUFF_T *rb)
{
#ifdef SR_USE_OS
  SR_OsMutexTake(rb->mutex,OS_WAIT_FOREVER);  //上锁
#endif

  rb->head=0;
  rb->tail=0;
  rb->curLen=0;

#ifdef SR_USE_OS
  SR_OsMutexRelease(rb->mutex);  //关锁
#endif
}





