refactor: string extend method

This commit is contained in:
2025-09-07 22:36:30 +02:00
parent 3e0584d139
commit 16ee246956
17 changed files with 2164 additions and 2123 deletions

View File

@@ -1,141 +1,141 @@
#include "myqueue.h"
#include <stdlib.h>
#include <string.h>
mcl_queue_s *mcl_queue_new(size_t queue_size, size_t elem_size) {
mcl_queue_s *queue = malloc(sizeof(mcl_queue_s));
if (queue == NULL) {
return NULL;
}
queue->buffer = malloc(queue_size * elem_size);
if (queue->buffer == NULL) {
free(queue);
return NULL;
}
int ret = mtx_init(&queue->lock, mtx_plain);
if (ret != thrd_success) {
free(queue->buffer);
free(queue);
return NULL;
}
queue->front = 0;
queue->rear = 0;
queue->size = 0;
queue->capacity = queue_size;
queue->elem_size = elem_size;
return queue;
}
int mcl_queue_push(mcl_queue_s *queue, const void *elem) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == queue->capacity) {
/* Queue full */
mtx_unlock(&queue->lock);
return -1;
}
/* Copy the elem in the buffer */
void *dest = (char *)queue->buffer + (queue->rear * queue->elem_size);
memcpy(dest, elem, queue->elem_size);
queue->size++;
queue->rear = (queue->rear + 1) % queue->capacity;
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_pop(mcl_queue_s *queue, void *out_elem) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
/* Queue empty */
mtx_unlock(&queue->lock);
return -1;
}
void *src = (char *)queue->buffer + (queue->front * queue->elem_size);
memcpy(out_elem, src, queue->elem_size);
queue->front = (queue->front + 1) % queue->capacity;
queue->size--;
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_get_front(mcl_queue_s *queue, void *out) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
mtx_unlock(&queue->lock);
return -1;
}
void *front = (char *)queue->buffer + (queue->front * queue->elem_size);
memcpy(out, front, queue->elem_size);
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_get_rear(mcl_queue_s *queue, void *out) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
mtx_unlock(&queue->lock);
return -1;
}
size_t rear_index;
if (queue->rear == 0) {
rear_index = queue->capacity - 1;
} else {
rear_index = queue->rear - 1;
}
void *rear = (char *)queue->buffer + (rear_index * queue->elem_size);
memcpy(out, rear, queue->elem_size);
mtx_unlock(&queue->lock);
return 0;
}
void mcl_queue_free(mcl_queue_s *queue) {
if (queue == NULL) {
return;
}
mtx_destroy(&queue->lock);
free(queue->buffer);
free(queue);
}
#include "myqueue.h"
#include <stdlib.h>
#include <string.h>
mcl_queue_s *mcl_queue_new(size_t queue_size, size_t elem_size) {
mcl_queue_s *queue = malloc(sizeof(mcl_queue_s));
if (queue == NULL) {
return NULL;
}
queue->buffer = malloc(queue_size * elem_size);
if (queue->buffer == NULL) {
free(queue);
return NULL;
}
int ret = mtx_init(&queue->lock, mtx_plain);
if (ret != thrd_success) {
free(queue->buffer);
free(queue);
return NULL;
}
queue->front = 0;
queue->rear = 0;
queue->size = 0;
queue->capacity = queue_size;
queue->elem_size = elem_size;
return queue;
}
int mcl_queue_push(mcl_queue_s *queue, const void *elem) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == queue->capacity) {
/* Queue full */
mtx_unlock(&queue->lock);
return -1;
}
/* Copy the elem in the buffer */
void *dest = (char *)queue->buffer + (queue->rear * queue->elem_size);
memcpy(dest, elem, queue->elem_size);
queue->size++;
queue->rear = (queue->rear + 1) % queue->capacity;
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_pop(mcl_queue_s *queue, void *out_elem) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
/* Queue empty */
mtx_unlock(&queue->lock);
return -1;
}
void *src = (char *)queue->buffer + (queue->front * queue->elem_size);
memcpy(out_elem, src, queue->elem_size);
queue->front = (queue->front + 1) % queue->capacity;
queue->size--;
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_get_front(mcl_queue_s *queue, void *out) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
mtx_unlock(&queue->lock);
return -1;
}
void *front = (char *)queue->buffer + (queue->front * queue->elem_size);
memcpy(out, front, queue->elem_size);
mtx_unlock(&queue->lock);
return 0;
}
int mcl_queue_get_rear(mcl_queue_s *queue, void *out) {
int ret = mtx_lock(&queue->lock);
if (ret != thrd_success) {
return -1;
}
if (queue->size == 0) {
mtx_unlock(&queue->lock);
return -1;
}
size_t rear_index;
if (queue->rear == 0) {
rear_index = queue->capacity - 1;
} else {
rear_index = queue->rear - 1;
}
void *rear = (char *)queue->buffer + (rear_index * queue->elem_size);
memcpy(out, rear, queue->elem_size);
mtx_unlock(&queue->lock);
return 0;
}
void mcl_queue_free(mcl_queue_s *queue) {
if (queue == NULL) {
return;
}
mtx_destroy(&queue->lock);
free(queue->buffer);
free(queue);
}

View File

@@ -1,72 +1,72 @@
#ifndef MYCLIB_QUEUE_H
#define MYCLIB_QUEUE_H
#include <stddef.h>
#include <threads.h>
/**
* @brief A simple circular queue (ring buffer).
*/
typedef struct mcl_queue {
size_t front; /**< Index of the next element to read. */
size_t rear; /**< Index where the next element will be written. */
size_t size; /**< Current number of elements in the queue. */
size_t capacity; /**< Maximum number of elements the queue can hold. */
size_t elem_size; /**< Size in bytes of each element. */
void *buffer; /**< Memory buffer that holds the elements. */
mtx_t lock; /**< Mutex to protect concurrent access. */
} mcl_queue_s;
/**
* @brief Create and initialize a new queue.
*
* @param queue_size Number of elements the queue can hold.
* @param elem_size Size in bytes of each element.
* @return Pointer to the new queue, or NULL on failure.
*/
mcl_queue_s *mcl_queue_new(size_t queue_size, size_t elem_size);
/**
* @brief Add an element to the queue.
*
* @param queue Pointer to the queue.
* @param elem Pointer to the data to add.
* @return 0 on success, -1 if the queue is full or on error.
*/
int mcl_queue_push(mcl_queue_s *queue, const void *elem);
/**
* @brief Remove an element from the queue.
*
* @param queue Pointer to the queue.
* @param out_elem Pointer to memory where the removed element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_pop(mcl_queue_s *queue, void *out_elem);
/**
* @brief Copy the front element without removing it.
*
* @param queue Pointer to the queue.
* @param out Pointer to memory where the element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_get_front(mcl_queue_s *queue, void *out);
/**
* @brief Copy the last element without removing it.
*
* @param queue Pointer to the queue.
* @param out Pointer to memory where the element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_get_rear(mcl_queue_s *queue, void *out);
/**
* @brief Free all resources used by the queue.
*
* @param queue Pointer to the queue to free.
*/
void mcl_queue_free(mcl_queue_s *queue);
#endif // MYCLIB_QUEUE_H
#ifndef MYCLIB_QUEUE_H
#define MYCLIB_QUEUE_H
#include <stddef.h>
#include <threads.h>
/**
* @brief A simple circular queue (ring buffer).
*/
typedef struct mcl_queue {
size_t front; /**< Index of the next element to read. */
size_t rear; /**< Index where the next element will be written. */
size_t size; /**< Current number of elements in the queue. */
size_t capacity; /**< Maximum number of elements the queue can hold. */
size_t elem_size; /**< Size in bytes of each element. */
void *buffer; /**< Memory buffer that holds the elements. */
mtx_t lock; /**< Mutex to protect concurrent access. */
} mcl_queue_s;
/**
* @brief Create and initialize a new queue.
*
* @param queue_size Number of elements the queue can hold.
* @param elem_size Size in bytes of each element.
* @return Pointer to the new queue, or NULL on failure.
*/
mcl_queue_s *mcl_queue_new(size_t queue_size, size_t elem_size);
/**
* @brief Add an element to the queue.
*
* @param queue Pointer to the queue.
* @param elem Pointer to the data to add.
* @return 0 on success, -1 if the queue is full or on error.
*/
int mcl_queue_push(mcl_queue_s *queue, const void *elem);
/**
* @brief Remove an element from the queue.
*
* @param queue Pointer to the queue.
* @param out_elem Pointer to memory where the removed element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_pop(mcl_queue_s *queue, void *out_elem);
/**
* @brief Copy the front element without removing it.
*
* @param queue Pointer to the queue.
* @param out Pointer to memory where the element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_get_front(mcl_queue_s *queue, void *out);
/**
* @brief Copy the last element without removing it.
*
* @param queue Pointer to the queue.
* @param out Pointer to memory where the element will be copied.
* @return 0 on success, -1 if the queue is empty or on error.
*/
int mcl_queue_get_rear(mcl_queue_s *queue, void *out);
/**
* @brief Free all resources used by the queue.
*
* @param queue Pointer to the queue to free.
*/
void mcl_queue_free(mcl_queue_s *queue);
#endif // MYCLIB_QUEUE_H