I have been working on a mechanism to queue up strings coming into a system via a USART and have implemented it as a singly linked list. I have done my best to profile the code and its memory usage at runtime depending on the amount of data fed to the data structure, but can anyone see anything "wrong" or less than desirable in the code?
StringQueue.h
/**
* @author Luke R Gary
* @date 6/1/2015
*
* @note Not debugged, prolly leakier than a diarrhea butt
*
* @note Look for a way to implement this driver to store strings in flash memory at the expense of
* allocation/traverse time
*/
#ifndef StringQueue_h
#define StringQueue_h
#include "stdlib.h"
#include "stdint.h"
#include "string.h"
#include "stdio.h"
#define MAX_ELEMENTS 32
//!<@struct node_t
typedef struct
{
char * data; //!< string for node data
struct node_t * nextNode; //!< link to next node, may be NULL to indicate rear
}node_t;
//!<@strqueue_t
typedef struct
{
node_t *front; //!< front node
node_t *rear; //!< rear node
uint8_t nodeCount; //!< current number of nodes
uint8_t maxElements; //!< maximum number of nodes
}strqueue_t;
///
extern char * queueFront(strqueue_t * queue);
///
extern uint8_t enqueue(strqueue_t * queue, const char * str);
///
__inline__ void removeData(node_t * node)
{
char * str = node->data;
free(str);
}
///
extern char * dequeue(strqueue_t * queue);
///
extern uint8_t queueIsEmpty(const strqueue_t * queue);
///
extern void queueDisplay(strqueue_t * queue);
///
extern void queueCreate(strqueue_t * queue, uint8_t elements);
///
extern uint8_t queueSize(const strqueue_t * queue);
///
extern uint8_t queueIsFull(const strqueue_t * queue);
#endif
StringQueue.c
/**
* @author Luke R Gary
* @date 6/1/2015
*
* @note Not debugged, prolly leakier than a diarrhea butt
*/
#include "StringQueue.h"
/**
* @brief returns string at the front of the queue
* @details [long description]
*
* @param queue a queue structure reference
* @return pointer to string
*/
char * queueFront(strqueue_t * queue)
{
if ((queue->front != NULL) && (queue->rear != NULL))
return (queue->front->data);
else
return 0;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @param str [description]
*
* @return [description]
*/
uint8_t enqueue(strqueue_t * queue, const char * str)
{
// if first element and last element in queue. i.e. no allocations yet
if(queue->front == NULL)
{
queue->rear = (node_t *)malloc(sizeof(node_t));
queue->rear->nextNode = NULL; // null link
queue->rear->data = malloc(strlen(str) + 1);
queue->rear->data = strncpy(queue->rear->data, (char *)str, strlen(str));
queue->front = queue->rear;
}
// if any elements exist so fart
else
{
node_t *temp = (node_t *)malloc(sizeof(node_t));
queue->rear->nextNode = temp; // link to next rear node
temp->data = malloc(strlen(str) + 1);
temp->data = strncpy(temp->data, (char *)str, strlen(str));
temp->nextNode = NULL; //ensure rear maintains null link
queue->rear = temp;
}
return queue->nodeCount++;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @return [description]
*/
char * dequeue(strqueue_t * queue)
{
node_t * temp = queue->front;
if(queue->front == NULL)
{
return NULL;
}
if(queue->front == queue->rear)
{
queue->front = NULL;
queue->rear = NULL;
}
else
{
queue->front = (node_t *)queue->front->nextNode;
}
queue->nodeCount--;
removeData(temp);
free(temp);
return queue->front->data;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @return [description]
*/
uint8_t queueIsEmpty(const strqueue_t *queue)
{
if(queue->front == NULL && queue->rear == NULL && queue->nodeCount == 0)
return 1;
else
return 0;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @return [description]
*/
void queueDisplay(strqueue_t *queue)
{
node_t * tempNode = queue->front;
while(tempNode != NULL)
{
printf("%s\n", tempNode->data);
tempNode = tempNode->nextNode;
}
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @param elements [description]
*/
void queueCreate(strqueue_t * queue, uint8_t elements)
{
queue->front = NULL;
queue->rear = NULL;
queue->nodeCount = 0;
if(elements == 0)
queue->maxElements = MAX_ELEMENTS;
else
queue->maxElements = elements;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @return [description]
*/
uint8_t queueSize(const strqueue_t * queue)
{
return queue->nodeCount;
}
/**
* @brief [brief description]
* @details [long description]
*
* @param queue a queue structure reference
* @return [description]
*/
uint8_t queueIsFull(const strqueue_t *queue)
{
if(queue->front != NULL && queue->nodeCount >= MAX_ELEMENTS)
return 1;
else
return 0;
}