361 lines
12 KiB
C
361 lines
12 KiB
C
#include "ivec_cmplx_queue.h"
|
|
#include "stdint.h"
|
|
#include "string.h"
|
|
//#include "ivec_bsw_common.h"
|
|
|
|
// #define IVEC_BSW_LOG(LOG_STRING,msg, ...)
|
|
#define LOG_STRING "ivec-cmplx-queue"
|
|
#define FIXED_EXTRA_SIZE 8
|
|
|
|
|
|
/**
|
|
* @brief Search for character in circular pu8Buffer and it does not return if null character is found
|
|
*
|
|
* @param start start address of pu8Buffer
|
|
* @param max size of pu8Buffer
|
|
* @param cur_idx start point to search from
|
|
* @param chr character to search
|
|
* @param len total length to search
|
|
* @return uint8_t* address of found character else NULL
|
|
*/
|
|
uint8_t* __prvCMPLX_Strnchr(uint8_t* start, int max, int cur_idx, uint8_t* substring, int substring_len, int len)
|
|
{
|
|
if (cur_idx<0 || cur_idx>max)
|
|
return NULL;
|
|
uint8_t* string = start;
|
|
int i = 0;
|
|
while (len--)
|
|
{
|
|
if ((cur_idx + i) >= max)
|
|
{
|
|
i = 0;
|
|
cur_idx = 0;
|
|
}
|
|
if (string[cur_idx + i] == substring[0])
|
|
{
|
|
int l_sub_string_found = 0;
|
|
int cur_i_idx = cur_idx + i + 1;
|
|
for (int j = 1;j < substring_len;j++)
|
|
{
|
|
l_sub_string_found = 1;
|
|
if (cur_i_idx >= max)
|
|
{
|
|
cur_i_idx = 0;
|
|
}
|
|
if (string[cur_i_idx] != substring[j])
|
|
{
|
|
l_sub_string_found = 0;
|
|
break;
|
|
}
|
|
cur_i_idx++;
|
|
|
|
}
|
|
if (l_sub_string_found)
|
|
return &string[cur_idx + i];
|
|
}
|
|
i++;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* @brief returns if queue is full or not
|
|
*
|
|
* @param queue queue handle
|
|
* @return uint32_t
|
|
* if i32QueueType==FIXED_ELEMENT_SIZE_QUEUE
|
|
* true if size is full else false
|
|
* else if i32QueueType==NONFIXED_ELEMENT_SIZE_QUEUE
|
|
* remaining size
|
|
*/
|
|
int i32CMPLX_FifoQueueFull(CmplxFifoQueueHandle_s* queue)
|
|
{
|
|
if (queue->u8Init == 0)
|
|
return 0;
|
|
if (queue->i32QueueType == NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
{
|
|
if (queue->i32Rear == queue->i32Front)
|
|
return queue->i32Filled == 0 ? (queue->i32TotalElements - (2 * queue->u8DelimeterLen + FIXED_EXTRA_SIZE)) : 0;
|
|
else
|
|
{
|
|
return (queue->i32Front > queue->i32Rear) ? ((queue->i32TotalElements - queue->i32Front) + (queue->i32Rear) - (2 * queue->u8DelimeterLen + FIXED_EXTRA_SIZE)) : (queue->i32Rear - queue->i32Front - (2 * queue->u8DelimeterLen + FIXED_EXTRA_SIZE));
|
|
}
|
|
}
|
|
else
|
|
return queue->i32Filled == queue->i32TotalElements ? 1 : 0;
|
|
}
|
|
/**
|
|
* @brief checks if queue is empty or not
|
|
*
|
|
* @param queue queue handle
|
|
* @return uint8_t 1 if queue is empty else 0
|
|
*/
|
|
uint8_t u8CMPLX_FifoQueueEmpty(CmplxFifoQueueHandle_s* queue)
|
|
{
|
|
if (queue->u8Init == 0)
|
|
return 0;
|
|
return queue->i32Filled == 0 ? 1 : 0;
|
|
}
|
|
/**
|
|
* @brief returs total elements present
|
|
*
|
|
* @param queue
|
|
* @return int
|
|
*/
|
|
int i32CMPLX_FifoCounts(CmplxFifoQueueHandle_s* queue)
|
|
{
|
|
if (queue->u8Init == 0)
|
|
return 0;
|
|
return queue->i32Filled;
|
|
}
|
|
/**
|
|
* @brief appends data to queue with circular implementation for fixed and non fixed element size
|
|
*
|
|
* @param queue handle
|
|
* @param data pu8Buffer to store from
|
|
* @param a_len total length to store (if i32QueueType==NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
* @return uint8_t 1 success 0 fail
|
|
*/
|
|
uint8_t u8CMPLX_FifoEnqueue(CmplxFifoQueueHandle_s* queue, void* data, int a_len)
|
|
{
|
|
if (queue->u8Init == 0 || data == NULL || a_len == 0)
|
|
return 0;
|
|
uint8_t* l_src = data;
|
|
uint8_t* l_dest = &queue->pu8Buffer[queue->i32Front * queue->i32ElementSize];
|
|
int l_len = queue->i32ElementSize;
|
|
int l_tail_remaining = 0;
|
|
if (queue->i32QueueType == NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
{
|
|
l_len = a_len;
|
|
if (i32CMPLX_FifoQueueFull(queue) <= l_len)
|
|
return 0;
|
|
for (int i = 0;i < queue->u8DelimeterLen;i++)
|
|
{
|
|
if (queue->i32Front >= queue->i32TotalElements)
|
|
{
|
|
queue->i32Front = 0;
|
|
}
|
|
queue->pu8Buffer[queue->i32Front++] = queue->u8Startdelimeter[i];
|
|
}
|
|
for (int i = 0;i < 4;i++)
|
|
{
|
|
if (queue->i32Front >= queue->i32TotalElements)
|
|
{
|
|
queue->i32Front = 0;
|
|
}
|
|
queue->pu8Buffer[queue->i32Front++] = (a_len >> (i * 8)) & 0xff;
|
|
}
|
|
if (queue->i32Front >= queue->i32TotalElements)
|
|
{
|
|
queue->i32Front = 0;
|
|
}
|
|
else if (a_len > (queue->i32TotalElements - queue->i32Front))
|
|
{
|
|
l_tail_remaining = (queue->i32TotalElements - queue->i32Front);
|
|
memcpy(&queue->pu8Buffer[queue->i32Front], l_src, l_tail_remaining);
|
|
queue->i32Front = 0;
|
|
}
|
|
if (a_len - l_tail_remaining > 0)
|
|
{
|
|
memcpy(&queue->pu8Buffer[queue->i32Front], (uint8_t*)(l_src + l_tail_remaining), a_len - l_tail_remaining);
|
|
queue->i32Front += (a_len - l_tail_remaining);
|
|
}
|
|
|
|
for (int i = 0;i < 4;i++)
|
|
{
|
|
if (queue->i32Front >= queue->i32TotalElements)
|
|
{
|
|
queue->i32Front = 0;
|
|
}
|
|
queue->pu8Buffer[queue->i32Front++] = (a_len >> (i * 8)) & 0xff;
|
|
}
|
|
for (int i = 0;i < queue->u8DelimeterLen;i++)
|
|
{
|
|
if (queue->i32Front >= queue->i32TotalElements)
|
|
{
|
|
queue->i32Front = 0;
|
|
}
|
|
queue->pu8Buffer[queue->i32Front++] = queue->u8EndDelimeter[i];
|
|
}
|
|
queue->i32Filled++;
|
|
queue->i32RemainingSize = i32CMPLX_FifoQueueFull(queue);
|
|
// queue->i32RemainingSize %= (queue->i32TotalElements);
|
|
// queue->i32Front %= (queue->i32TotalElements);
|
|
|
|
|
|
}
|
|
else {
|
|
if(queue->i32Filled>=queue->i32TotalElements)
|
|
return 0;
|
|
memcpy(l_dest, l_src, queue->i32ElementSize);
|
|
queue->i32Front++;
|
|
queue->i32Front %= (queue->i32TotalElements);
|
|
queue->i32Filled++;
|
|
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
/**
|
|
* @brief extarcts data from queue with circular implementation for fixed and non fixed element size
|
|
*
|
|
* @param queue handle
|
|
* @param data pu8Buffer to store to
|
|
* @param a_len length extracted (if i32QueueType==NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
* @param dump_element 1: dump element (useful if element not required)
|
|
* @return uint8_t 1:success 0: fail
|
|
*/
|
|
uint8_t u8CMPLX_FifoDequeue(CmplxFifoQueueHandle_s* queue, void* data, int* a_len, uint8_t dump_element)
|
|
{
|
|
if (queue->u8Init == 0 || (data == NULL && dump_element == 0) || a_len == NULL)
|
|
return 0;
|
|
*a_len = 0;
|
|
uint8_t* l_src = &queue->pu8Buffer[queue->i32Rear * queue->i32ElementSize];
|
|
uint8_t* l_dest = data;
|
|
// int l_len = queue->i32ElementSize;
|
|
if (queue->i32QueueType == NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
{
|
|
if (u8CMPLX_FifoQueueEmpty(queue))
|
|
return 0;
|
|
int l_queue_i32Rear = queue->i32Rear;
|
|
if (l_queue_i32Rear >= queue->i32TotalElements)
|
|
l_queue_i32Rear = 0;
|
|
uint8_t* l_start = __prvCMPLX_Strnchr(&queue->pu8Buffer[0], queue->i32TotalElements, l_queue_i32Rear, queue->u8Startdelimeter, queue->u8DelimeterLen, queue->i32TotalElements);
|
|
if (l_start == NULL)
|
|
return 2;
|
|
if (l_start - &queue->pu8Buffer[0] != l_queue_i32Rear)
|
|
{
|
|
//IVEC_BSW_LOG(LOG_STRING,"Anomly found %d-%d\n", l_queue_i32Rear, l_start - &queue->pu8Buffer[0]);
|
|
}
|
|
l_queue_i32Rear = l_start - &queue->pu8Buffer[0];
|
|
for (int i = 0;i < queue->u8DelimeterLen;i++)
|
|
{
|
|
l_queue_i32Rear++;
|
|
if (l_queue_i32Rear >= queue->i32TotalElements)
|
|
l_queue_i32Rear = 0;
|
|
}
|
|
int s_len = 0, e_len = 0;
|
|
for (int i = 0;i < 4;i++)
|
|
{
|
|
s_len |= (queue->pu8Buffer[l_queue_i32Rear] << i * 8);
|
|
l_queue_i32Rear++;
|
|
if (l_queue_i32Rear >= queue->i32TotalElements)
|
|
l_queue_i32Rear = 0;
|
|
}
|
|
if (s_len == 0)
|
|
return 3;
|
|
|
|
uint8_t* l_end = NULL;
|
|
int l_while_exit = 0;
|
|
while (1)
|
|
{
|
|
e_len = 0;
|
|
l_end = __prvCMPLX_Strnchr(&queue->pu8Buffer[0], queue->i32TotalElements, (l_end == NULL ? l_queue_i32Rear : (l_end - &queue->pu8Buffer[0] + 1)), queue->u8EndDelimeter, queue->u8DelimeterLen, queue->i32TotalElements);
|
|
if (l_end == NULL)
|
|
{
|
|
return 4;
|
|
}
|
|
int l_queue_i32Rear_temp = ((l_end - &queue->pu8Buffer[0] < 4) ? queue->i32TotalElements : 0) + (l_end - &queue->pu8Buffer[0]) - 4;
|
|
for (int i = 0;i < 4;i++)
|
|
{
|
|
e_len |= (queue->pu8Buffer[l_queue_i32Rear_temp] << i * 8);
|
|
l_queue_i32Rear_temp++;
|
|
if (l_queue_i32Rear_temp >= queue->i32TotalElements)
|
|
l_queue_i32Rear_temp = 0;
|
|
}
|
|
l_while_exit++;
|
|
if (l_while_exit > 100)
|
|
{
|
|
//IVEC_BSW_LOG(LOG_STRING,"return from while %d-%d-%d", s_len, e_len, l_queue_i32Rear_temp);
|
|
return 5;
|
|
}
|
|
if (s_len != e_len)
|
|
{
|
|
//IVEC_BSW_LOG(LOG_STRING,"Invalid Length %d-%d-%d", s_len, e_len, l_queue_i32Rear_temp);
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
int len1 = ((queue->i32TotalElements - l_queue_i32Rear) < s_len) ? (queue->i32TotalElements - l_queue_i32Rear) : s_len;
|
|
int len2 = s_len - len1;
|
|
|
|
if (len1)
|
|
{
|
|
if (!dump_element)
|
|
memcpy(data, &queue->pu8Buffer[l_queue_i32Rear], len1);
|
|
l_queue_i32Rear += (len1 - 1);
|
|
}
|
|
if (len2)
|
|
{
|
|
if (!dump_element)
|
|
memcpy((uint8_t*)data + len1, &queue->pu8Buffer[0], len2);
|
|
l_queue_i32Rear = (len2 - 1);
|
|
}
|
|
|
|
|
|
for (int i = 0;i < queue->u8DelimeterLen + 4 + 1;i++)
|
|
{
|
|
l_queue_i32Rear++;
|
|
if (l_queue_i32Rear >= queue->i32TotalElements)
|
|
l_queue_i32Rear = 0;
|
|
}
|
|
*a_len = s_len;
|
|
//l_len = s_len;
|
|
//IVEC_BSW_LOG(LOG_STRING,"deque:%d-%d-%d\n", l_start - queue->pu8Buffer, l_end - queue->pu8Buffer, s_len);
|
|
queue->i32Rear = l_queue_i32Rear;
|
|
|
|
queue->i32Filled--;
|
|
queue->i32RemainingSize = i32CMPLX_FifoQueueFull(queue);
|
|
// queue->i32RemainingSize %= queue->i32TotalElements;
|
|
// queue->i32Rear %= (queue->i32TotalElements);
|
|
}
|
|
else {
|
|
if(queue->i32Filled<=0)
|
|
return 0;
|
|
if (!dump_element)
|
|
memcpy(l_dest, l_src, queue->i32ElementSize);
|
|
queue->i32Rear++;
|
|
queue->i32Rear %= (queue->i32TotalElements);
|
|
queue->i32Filled--;
|
|
}
|
|
|
|
|
|
return 1;
|
|
}
|
|
/**
|
|
* @brief initilises queue
|
|
*
|
|
* @param queue
|
|
* @return uint8_t 1:success 0:fail
|
|
*/
|
|
uint8_t u8CMPLX_FifoQueueInit(CmplxFifoQueueHandle_s* queue)
|
|
{
|
|
if (queue == NULL || queue->pu8Buffer == NULL)
|
|
{
|
|
queue->u8Init = 0;
|
|
return 0;
|
|
}
|
|
if (queue->i32QueueType == NONFIXED_ELEMENT_SIZE_QUEUE)
|
|
queue->i32ElementSize = 1;
|
|
queue->i32Rear = 0;
|
|
queue->i32Front = 0;
|
|
queue->i32RemainingSize = queue->i32TotalElements;
|
|
queue->i32Filled = 0;
|
|
queue->u8Init = 1;
|
|
|
|
// IVEC_BSW_LOG(LOG_STRING,"Initlising queue with size %lu-%lu-%d-%c-%c\n", queue->i32ElementSize, queue->i32TotalElements, queue->i32QueueType, queue->u8Startdelimeter, queue->u8EndDelimeter);
|
|
|
|
return 1;
|
|
}
|
|
void vCMPLX_FifoQueueFlush(CmplxFifoQueueHandle_s* queue)
|
|
{
|
|
//IVEC_BSW_LOG(LOG_STRING,"Flushing queue\n");
|
|
if(queue!=NULL && queue->pu8Buffer!=NULL)
|
|
memset(queue->pu8Buffer, 0, queue->i32TotalElements*queue->i32ElementSize);
|
|
queue->i32Rear = 0;
|
|
queue->i32Front = 0;
|
|
queue->i32RemainingSize = queue->i32TotalElements;
|
|
queue->i32Filled = 0;
|
|
}
|