mirror of
https://gitee.com/Lamdonn/varch.git
synced 2025-12-07 01:06:41 +08:00
194 lines
4.8 KiB
C
194 lines
4.8 KiB
C
/*********************************************************************************************************
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* file description
|
|
* ------------------------------------------------------------------------------------------------------
|
|
* \file queue.c
|
|
* \unit queue
|
|
* \brief This is a C language queue
|
|
* \author Lamdonn
|
|
* \version v1.0.0
|
|
* \license GPL-2.0
|
|
* \copyright Copyright (C) 2023 Lamdonn.
|
|
********************************************************************************************************/
|
|
#include "queue.h"
|
|
#include <string.h>
|
|
|
|
typedef struct QUEUE
|
|
{
|
|
void* base; /**< base address of data */
|
|
int cst; /**< base const */
|
|
int dsize; /**< size of queue data */
|
|
int capacity; /**< capacity of queue */
|
|
int size; /**< size of queue */
|
|
int head; /**< index of queue head */
|
|
int tail; /**< index of queue tail */
|
|
} QUEUE;
|
|
|
|
/* Address of queue array */
|
|
#define at(i) (((unsigned char *)(queue->base))+(i)*(queue->dsize))
|
|
|
|
queue_t queue_create(int dsize, int capacity, void *base)
|
|
{
|
|
queue_t queue;
|
|
|
|
/* Input value validity check */
|
|
if (dsize <= 0) return NULL;
|
|
if (capacity <= 0) return NULL;
|
|
|
|
/* Allocate memory for the QUEUE structure */
|
|
queue = (queue_t)malloc(sizeof(QUEUE));
|
|
if (!queue) return NULL;
|
|
|
|
/* Initialize structural parameters */
|
|
queue->base = base;
|
|
queue->cst = 1;
|
|
queue->capacity = capacity;
|
|
queue->dsize = dsize;
|
|
queue->tail = 0;
|
|
queue->head = 0;
|
|
queue->size = 0;
|
|
|
|
/* Dynamically allocate an array without passing it in */
|
|
if (!queue->base)
|
|
{
|
|
queue->base = malloc(dsize * capacity);
|
|
queue->cst = 0;
|
|
}
|
|
|
|
/* Check if the array space is valid */
|
|
if (!queue->base)
|
|
{
|
|
queue_delete(queue);
|
|
return NULL;
|
|
}
|
|
|
|
return queue;
|
|
}
|
|
|
|
void queue_delete(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return;
|
|
|
|
/* If it is not a constant array but a dynamic array, release the allocated space */
|
|
if (!queue->cst && queue->base) free(queue->base);
|
|
|
|
/* Free queue structure */
|
|
free(queue);
|
|
}
|
|
|
|
int queue_push(queue_t queue, void* data)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Check if the queue is full */
|
|
if (queue_full(queue)) return 0;
|
|
|
|
/* Assigning data to the queue */
|
|
if (data) memcpy(at(queue->tail), data, queue->dsize);
|
|
|
|
/* Update queue status */
|
|
queue->tail = (queue->tail + 1) % queue->capacity;
|
|
queue->size++;
|
|
|
|
return 1;
|
|
}
|
|
|
|
int queue_pop(queue_t queue, void* data)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Check if the queue is full */
|
|
if (queue_empty(queue)) return 0;
|
|
|
|
/* Assigning data from the queue */
|
|
if (data) memcpy(data, at(queue->head), queue->dsize);
|
|
|
|
/* Update queue status */
|
|
queue->head = (queue->head + 1) % queue->capacity;
|
|
queue->size--;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void queue_clear(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return;
|
|
|
|
/* Reset queue status */
|
|
queue->tail = 0;
|
|
queue->head = 0;
|
|
queue->size = 0;
|
|
}
|
|
|
|
int queue_index(queue_t queue, int index)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return -1;
|
|
if (index < 0 || index >= queue->size) return -1;
|
|
|
|
/* Starting from the head, calculate the data index */
|
|
return (queue->head + index) % (queue->capacity);
|
|
}
|
|
|
|
void* queue_data(queue_t queue, int index)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return NULL;
|
|
|
|
/* Get indexe for accessing data */
|
|
index = queue_index(queue, index);
|
|
if (index < 0) return NULL;
|
|
|
|
/* Return array address based on index */
|
|
return (void*)at(index);
|
|
}
|
|
|
|
int queue_size(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Return queue size */
|
|
return queue->size;
|
|
}
|
|
|
|
int queue_capacity(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Return queue capacity */
|
|
return queue->capacity;
|
|
}
|
|
|
|
int queue_dsize(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Return queue data size */
|
|
return queue->dsize;
|
|
}
|
|
|
|
int queue_empty(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 1;
|
|
|
|
/* Determine if size is 0 */
|
|
return (queue->size == 0) ? 1 : 0;
|
|
}
|
|
|
|
int queue_full(queue_t queue)
|
|
{
|
|
/* Input value validity check */
|
|
if (!queue) return 0;
|
|
|
|
/* Determine if size is capacity */
|
|
return (queue->size == queue->capacity) ? 1 : 0;
|
|
}
|