/*
 * =====================================================================================
 *       Copyright (c), 2013-2020, Jz.
 *       Filename:  ringbuffer.h
 *       Author:  linux kernel, 
 *   Organization:  jz
 *
 * =====================================================================================
 */
 /*************************************************  
  File name     : ringbuffer.h
  Module        : common
  Author        : amir  
  Created on    : 2023-01-6    
  Description   :
      a ringbuffer to store data(copy)
    
  Modify History:   
  1. Date:        Author:         Modification:
*************************************************/
#ifndef __RINGBUFFER_H__
#define __RINGBUFFER_H__
#include <stdint.h>
#include "list.h"
#include "hmutex.h"
#include "hbase.h"

enum{
 	RING_LIST_FREE = 0,
	RING_LIST_USING,
	RING_LIST_MAX,
};

typedef struct{
	struct list_head link;
	int8_t   		 *pos;
	uint32_t		  size;
	uint32_t 		  seq; /* start from 0, 不是视频的seq, ringbuffer 内部的seq */
}ring_item;

typedef struct{
	struct list_head list[RING_LIST_MAX];
	hmutex_t 	     mutex;
    hsem_t           sem;
    int8_t   		 *buffer;/* the buffer holding the data */
    uint32_t 		 capacity;/* the capacity of the allocated buffer */
    int8_t			 *write;/* data is added at offset (write % size) */
    int8_t	 		 *read;/* data is extracted from off. (read % size) */
	ring_item		 *latest_item; /* 最新一个 item, seq 第一个为0, 并自增, 无的时候是 UINT32_MAX*/
    uint32_t		  last_drop_seq; /* 最后因buffer不足,被丢弃的seq*/
}ringbuffer;


ringbuffer * ringbuffer_init(uint32_t size);

void ringbuffer_deinit(ringbuffer *rb);

void ringbuffer_reset(ringbuffer *rb);

//put in data
/*
 * 返回被最后丢掉的seq
*/
#define ringbuffer_put(_fifo, _data, _size) ringbuffer_put2(_fifo, _data, _size, NULL, 0)

//put in 2 data
/*
 * 返回被最后新增的item
 */
ring_item *ringbuffer_put2(ringbuffer *rb, const char *data1, uint32_t data1_size, const char *data2, uint32_t data2_size);

//pop out data
int32_t ringbuffer_pop(ringbuffer *rb, char *to, uint32_t *len);

//get the size of data in ringbuffer
int32_t ringbuffer_size(ringbuffer *rb);

//get the hv_free size of data in ringbuffer

int32_t ringbuffer_get_freesize(ringbuffer *rb);

/*
 * 返回UINT32_MAX无数据
*/
uint32_t ringbuffer_get_lastseq_locked(ringbuffer *rb);


//get the count of items in ringbuffer
int32_t ringbuffer_item_count(ringbuffer *rb);

void ringbuffer_dump(ringbuffer *rb);

int32_t ringbuffer_test();
#endif
