C语言动态缓冲区设计


#ifndef __RINGBUFFER__H_
#define __RINGBUFFER__H_

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef unsigned char UCHAR;
typedef unsigned int  UINT;


/* Circular elements object */
typedef struct{ 
    int         size;   /* maximum number of elements           */
    int         pre_read_index;  /*last packet head index,this packet is correct*/
    int         cur_read_index;     /*current index of read*/
    int         write_index;    /* index at which to write new element  */
    UCHAR*      elements;  /* vector of elements                   */
}CircularBuffer;


typedef struct{ 
    pthread_mutex_t mutex;
    pthread_mutex_t write_locker;
    pthread_cond_t notEmpty;  
    pthread_cond_t notFull;		
    CircularBuffer cir_buffer;
}RingBuffer;



/*ring_buffer api*/
extern bool RingBufferInit(RingBuffer *ring_buffer, int size);
extern bool RingBufferDeInit(RingBuffer *ring_buffer);
extern bool Clean(RingBuffer *ring_buffer);
extern bool IsFull(RingBuffer *ring_buffer);
extern bool IsEmpty(RingBuffer *ring_buffer);
extern void Info(RingBuffer *ring_buffer);
extern void InfoWrite(RingBuffer *ring_buffer);
extern void InfoRead(RingBuffer *ring_buffer);
extern int AvailableSize(RingBuffer *ring_buffer);

extern int Write(RingBuffer *ring_buffer, UCHAR* msg, int len);
extern int ReadOne(RingBuffer *ring_buffer, UCHAR* msg);
extern int Read(RingBuffer *ring_buffer, UCHAR* msg, int length);
extern bool ReadOffset(RingBuffer *ring_buffer, UCHAR* msg, int offset, int length);

extern int GetSize(RingBuffer *ring_buffer);
extern bool ReturnToPre(RingBuffer *ring_buffer); 	/*error happened ,need to return to last right packet head*/
extern void PreToCurrentRead(RingBuffer *ring_buffer);
extern int ReturnCurrentIndex(RingBuffer *ring_buffer); /*return the length between current index and protocol head*/



#endif   /*__RINGBUFFER__H_*/


#include "ringbuffer.h"

bool RingBufferInit(RingBuffer *ring_buffer,int size)
{
    if(ring_buffer==NULL || !size) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }


    pthread_mutex_init(&ring_buffer->mutex, NULL);
    pthread_cond_init(&ring_buffer->notEmpty, NULL); /* if ringbuffer can read or not */
    pthread_cond_init(&ring_buffer->notFull, NULL);   /* if ringbuffer can write or not */
    ring_buffer->cir_buffer.size  = size + 1; /* include empty elem */
    ring_buffer->cir_buffer.pre_read_index = 0;
    ring_buffer->cir_buffer.cur_read_index = 0;
    ring_buffer->cir_buffer.write_index   = 0;
    ring_buffer->cir_buffer.elements = (UCHAR*)malloc(ring_buffer->cir_buffer.size);

    if(ring_buffer->cir_buffer.elements == NULL)
    {
        printf("Error: malloc error.\n");
        return false;
    }

    return true;
}


bool RingBufferDeInit(RingBuffer *ring_buffer)
{
    printf("Ring-Buffer de-init...\n");
    
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    pthread_mutex_lock(&ring_buffer->mutex);
    free(ring_buffer->cir_buffer.elements); /* OK if null */
    pthread_mutex_unlock(&ring_buffer->mutex);

    return true;
}


bool Clean(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    ring_buffer->cir_buffer.pre_read_index = 0;
    ring_buffer->cir_buffer.cur_read_index = 0;
    ring_buffer->cir_buffer.write_index = 0;
    memset(ring_buffer->cir_buffer.elements, 0, ring_buffer->cir_buffer.size);
    
    return true;
}

bool IsFull(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    if((ring_buffer->cir_buffer.write_index + 1) % ring_buffer->cir_buffer.size == ring_buffer->cir_buffer.pre_read_index)
    {
		return true;
    }
    return false;
}

bool IsEmpty(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    if (ring_buffer->cir_buffer.write_index == ring_buffer->cir_buffer.cur_read_index)
    {
		return true;
    }

    return false;
}
 
void Info(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return ;
    }

    if(ring_buffer->cir_buffer.elements != NULL)
    {
        printf("Info: elements: %s\n", ring_buffer->cir_buffer.elements);
    }

}

void InfoWrite(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf( "Error: ring_buffer is null.\n");
        return ;
    }

    if(ring_buffer->cir_buffer.elements != NULL)
    {
        printf("InfoWrite: elements: %s\n", ring_buffer->cir_buffer.elements);
    }

}

void InfoRead(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return ;
    }


    if(ring_buffer->cir_buffer.elements != NULL)
    {
        printf("InfoRead: elements: %s\n", ring_buffer->cir_buffer.elements);
    }

}

int AvailableSize(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    int length = 0;
	
     
    if(ring_buffer->cir_buffer.write_index >= ring_buffer->cir_buffer.pre_read_index)
    {
		length = ring_buffer->cir_buffer.write_index - ring_buffer->cir_buffer.pre_read_index;
    }
    else
    {
		length = ring_buffer->cir_buffer.size - ring_buffer->cir_buffer.pre_read_index + ring_buffer->cir_buffer.write_index;
    }
    return length;
}



int Write(RingBuffer *ring_buffer, UCHAR* msg, int len)
{
    int count = 0;
	UCHAR *p = msg;
    
	if(ring_buffer == NULL || msg == NULL) 
    {
        printf("RingBuffer object %p, write elements %p.\n", ring_buffer, msg);
        return -1;
    }

    if (len <= 0) {
        printf( "invalid write length %d.\n", len);
        return -1;
	}
	pthread_mutex_lock(&ring_buffer->mutex);
    while(len--)
    {
		while (IsFull(ring_buffer))
		{
			pthread_cond_wait(&ring_buffer->notFull, &ring_buffer->mutex);
		}

		memcpy(ring_buffer->cir_buffer.elements + ring_buffer->cir_buffer.write_index, p++, 1);
		ring_buffer->cir_buffer.write_index = (ring_buffer->cir_buffer.write_index + 1) % ring_buffer->cir_buffer.size;
         
	    count++;
    }
	pthread_cond_signal(&ring_buffer->notEmpty);
	pthread_mutex_unlock(&ring_buffer->mutex); 
    return count ;
}


int ReadOne(RingBuffer *ring_buffer, UCHAR* msg) {
	return Read(ring_buffer, msg, 1);
}

int Read(RingBuffer *ring_buffer, UCHAR* msg, int length)
{
    int count = 0;
	UCHAR* p = msg;
	
    if(ring_buffer == NULL || msg == NULL) 
    {
        printf("RingBuffer object %p, read elements %p.\n", ring_buffer, msg);
        return -1;
    }

    if(length <= 0) {
        printf("invalid read length %d.\n", length);
		return -1;
	} 
    
	pthread_mutex_lock(&ring_buffer->mutex);	
    while(length--)
    {
		while(IsEmpty(ring_buffer))
		{
			pthread_cond_wait(&ring_buffer->notEmpty, &ring_buffer->mutex);	
		}
		memcpy(p, ring_buffer->cir_buffer.elements + ring_buffer->cir_buffer.cur_read_index, 1);
		ring_buffer->cir_buffer.cur_read_index = (ring_buffer->cir_buffer.cur_read_index + 1) % ring_buffer->cir_buffer.size;
		++ p;
		count++;
    }
	pthread_cond_signal(&ring_buffer->notFull);
	pthread_mutex_unlock(&ring_buffer->mutex);
    return count;
}

bool ReadOffset(RingBuffer *ring_buffer, UCHAR* msg, int offset, int length)
{
    ReturnToPre(ring_buffer);
    int count = 0;
    if(offset < 0)
    {
        printf("offset < 0\n");
        return false;
    }
    UCHAR tmp[offset];
    Read(ring_buffer, tmp, offset);
    Read(ring_buffer, msg, length);
    return true;	
}


int GetSize(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return -1;
    }

    return ring_buffer->cir_buffer.size;
}



bool ReturnToPre(RingBuffer *ring_buffer)
{
    if(ring_buffer==NULL) 
    {
        printf("Error: ring_buffer is null.\n");
        return false;
    }

    pthread_mutex_lock(&ring_buffer->mutex);
    ring_buffer->cir_buffer.cur_read_index = ring_buffer->cir_buffer.pre_read_index;
    pthread_mutex_unlock(&ring_buffer->mutex);

    return true;
}

void PreToCurrentRead(RingBuffer *ring_buffer)
{
    pthread_mutex_lock(&ring_buffer->mutex);
    ring_buffer->cir_buffer.pre_read_index = ring_buffer->cir_buffer.cur_read_index;
    pthread_mutex_unlock(&ring_buffer->mutex);
}

int ReturnCurrentIndex(RingBuffer *ring_buffer)
{
    int index = 0;
    pthread_mutex_lock(&ring_buffer->mutex);
    index = ring_buffer->cir_buffer.cur_read_index - ring_buffer->cir_buffer.pre_read_index;
    pthread_mutex_unlock(&ring_buffer->mutex);
    return index;
}








你可能感兴趣的:(c语言)