Skip to content

Commit

Permalink
v2.0:
Browse files Browse the repository at this point in the history
- No more inlines in header file (to generate proper static library)
- MISRA refactoring
  • Loading branch information
SMFSW committed Apr 16, 2024
1 parent 2a5c11a commit 9e0faf5
Show file tree
Hide file tree
Showing 7 changed files with 621 additions and 259 deletions.
293 changes: 207 additions & 86 deletions Doxyfile

Large diffs are not rendered by default.

293 changes: 207 additions & 86 deletions Doxyfile.auto

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2017-2022, SMFSW
Copyright (c) 2017-2024, SMFSW
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
6 changes: 5 additions & 1 deletion ReleaseNotes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Queue handling library (designed on Arduino)
2017-2022 SMFSW
2017-2024 SMFSW

Feel free to share your thoughts @ [email protected] about:
- issues encountered
Expand All @@ -10,6 +10,10 @@ Feel free to share your thoughts @ [email protected] about:

** Actual:

v2.0: 15 Apr 2024:
- No more inlines in header file (to generate proper static library)
- MISRA refactoring

v1.11: 18 Dec 2022:
- Include missing stddef.h

Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=Queue
version=1.11
version=2.0
author=SMFSW <[email protected]>
maintainer=SMFSW <[email protected]>
sentence=Queue handling library.
Expand Down
243 changes: 181 additions & 62 deletions src/cppQueue.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*!\file cppQueue.cpp
** \author SMFSW
** \copyright BSD 3-Clause License (c) 2017-2022, SMFSW
** \copyright BSD 3-Clause License (c) 2017-2024, SMFSW
** \brief cppQueue handling library (designed on Arduino)
** \details cppQueue handling library (designed on Arduino)
** This library was designed for Arduino, yet may be compiled without change with gcc for other purposes/targets
Expand All @@ -13,15 +13,21 @@
/****************************************************************/


#define QUEUE_INITIALIZED 0x5AA5U //!< Initialized cppQueue control value


/**************************/
/*** INTERNAL FUNCTIONS ***/
/**************************/
/*! \brief Increment index
** \details Increment buffer index \b pIdx rolling back to \b start when limit \b end is reached
** \param [in,out] pIdx - pointer to index value
** \param [in] end - counter upper limit value
** \param [in] start - counter lower limit value
**/
static inline void __attribute__((nonnull, always_inline)) inc_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)
static inline void __attribute__((nonnull, always_inline)) _inc_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)
{
if (*pIdx < end - 1) { (*pIdx)++; }
if (*pIdx < (end - 1U)) { (*pIdx)++; }
else { *pIdx = start; }
}

Expand All @@ -31,27 +37,62 @@ static inline void __attribute__((nonnull, always_inline)) inc_idx(uint16_t * co
** \param [in] end - counter upper limit value
** \param [in] start - counter lower limit value
**/
static inline void __attribute__((nonnull, always_inline)) dec_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)
static inline void __attribute__((nonnull, always_inline)) _dec_idx(uint16_t * const pIdx, const uint16_t end, const uint16_t start)
{
if (*pIdx > start) { (*pIdx)--; }
else { *pIdx = end - 1; }
else { *pIdx = end - 1U; }
}


/*! \brief get initialization state of the queue
** \return cppQueue initialization status
** \retval true if queue is allocated
** \retval false is queue is not allocated
**/
inline bool __attribute__((always_inline)) cppQueue::_isInitialized(void) {
return (init == QUEUE_INITIALIZED) ? true : false; }

/*! \brief get emptiness state of the queue
** \return cppQueue emptiness status
** \retval true if queue is empty
** \retval false is not empty
**/
inline bool __attribute__((always_inline)) cppQueue::_isEmpty(void) {
return (cnt == 0U) ? true : false; }

/*! \brief get fullness state of the queue
** \return cppQueue fullness status
** \retval true if queue is full
** \retval false is not full
**/
inline bool __attribute__((always_inline)) cppQueue::_isFull(void) {
return (cnt == rec_nb) ? true : false; }


/*! \brief get number of records in the queue
** \return Number of records stored in the queue
**/
inline uint16_t __attribute__((always_inline)) cppQueue::_getCount(void) {
return cnt; }


/************************/
/*** PUBLIC FUNCTIONS ***/
/************************/
cppQueue::cppQueue(const size_t size_rec, const uint16_t nb_recs, const cppQueueType type, const bool overwrite, void * const pQDat, const size_t lenQDat)
{
init = 0;
rec_nb = 0; // rec_nb needs to be 0 to ensure proper push behavior when queue is not allocated
ovw = 0; // ovw needs to be 0 to ensure proper push behavior when queue is not allocated
flush(); // other variables needs to be 0 to ensure proper functions behavior when queue is not allocated

const uint32_t size = nb_recs * size_rec;
const size_t size = nb_recs * size_rec;

dynamic = (pQDat == NULL) ? true : false;

if (dynamic) { queue = (uint8_t *) malloc(size); }
else if (lenQDat < size) { queue = NULL; } // Check static Queue data size
else { queue = (uint8_t *) pQDat; }
else if (lenQDat >= size) { queue = (uint8_t *) pQDat; }
else { queue = NULL; }

if (queue != NULL)
{
Expand All @@ -67,7 +108,7 @@ cppQueue::cppQueue(const size_t size_rec, const uint16_t nb_recs, const cppQueue

cppQueue::~cppQueue()
{
if ((init == QUEUE_INITIALIZED) && dynamic && (queue != NULL)) { free(queue); }
if (_isInitialized() && dynamic && (queue != NULL)) { free(queue); }
}


Expand All @@ -81,101 +122,179 @@ void cppQueue::flush(void)

bool __attribute__((nonnull)) cppQueue::push(const void * const record)
{
if ((!ovw) && isFull()) { return false; }
bool ret = true;

uint8_t * const pStart = queue + (rec_sz * in);
memcpy(pStart, record, rec_sz);

inc_idx(&in, rec_nb, 0);
if (_isFull()) // No more records available
{
if (ovw) // cppQueue is full, overwrite is allowed
{
if (impl == FIFO)
{
_inc_idx(&out, rec_nb, 0); // as oldest record is overwritten, increment out
}
//else if (impl == LIFO) {} // Nothing to do in this case
}
else
{
ret = false;
}
}
else
{
cnt++; // Increase records count
}

if (!isFull()) { cnt++; } // Increase records count
else if (ovw) // cppQueue is full and overwrite is allowed
if (ret)
{
if (impl == FIFO) { inc_idx(&out, rec_nb, 0); } // as oldest record is overwritten, increment out
//else if (impl == LIFO) {} // Nothing to do in this case
uint8_t * const pStart = queue + (rec_sz * in);
memcpy(pStart, record, rec_sz);
_inc_idx(&in, rec_nb, 0);
}

return true;
return ret;
}

bool __attribute__((nonnull)) cppQueue::pop(void * const record)
{
const uint8_t * pStart;

if (isEmpty()) { return false; } // No more records
bool ret = true;

if (impl == FIFO)
if (_isEmpty()) // No records
{
pStart = queue + (rec_sz * out);
inc_idx(&out, rec_nb, 0);
ret = false;
}
else if (impl == LIFO)
else
{
dec_idx(&in, rec_nb, 0);
pStart = queue + (rec_sz * in);
const uint8_t * pStart;

if (impl == FIFO)
{
pStart = queue + (rec_sz * out);
_inc_idx(&out, rec_nb, 0);
}
else /* if (impl == LIFO) */
{
_dec_idx(&in, rec_nb, 0);
pStart = queue + (rec_sz * in);
}

memcpy(record, pStart, rec_sz);
cnt--; // Decrease records count
}
else { return false; }

memcpy(record, pStart, rec_sz);
cnt--; // Decrease records count
return true;
return ret;
}


bool __attribute__((nonnull)) cppQueue::peek(void * const record)
{
const uint8_t * pStart;
bool ret = true;

if (isEmpty()) { return false; } // No more records

if (impl == FIFO)
if (_isEmpty()) // No records
{
pStart = queue + (rec_sz * out);
// No change on out var as it's just a peek
ret = false;
}
else if (impl == LIFO)
else
{
uint16_t rec = in; // Temporary var for peek (no change on in with dec_idx)
dec_idx(&rec, rec_nb, 0);
pStart = queue + (rec_sz * rec);
const uint8_t * pStart;

if (impl == FIFO)
{
pStart = queue + (rec_sz * out);
// No change on out var as it's just a peek
}
else /*if (impl == LIFO)*/
{
uint16_t rec = in; // Temporary var for peek (no change on in with dec_idx)
_dec_idx(&rec, rec_nb, 0);
pStart = queue + (rec_sz * rec);
}

memcpy(record, pStart, rec_sz);
}
else { return false; }

memcpy(record, pStart, rec_sz);
return true;
return ret;
}


bool cppQueue::drop(void)
{
if (isEmpty()) { return false; } // No more records
bool ret = true;

if (impl == FIFO) { inc_idx(&out, rec_nb, 0); }
else if (impl == LIFO) { dec_idx(&in, rec_nb, 0); }
else { return false; }
if (_isEmpty()) // No records
{
ret = false;
}
else
{
if (impl == FIFO)
{
_inc_idx(&out, rec_nb, 0);
}
else /*if (impl == LIFO)*/
{
_dec_idx(&in, rec_nb, 0);
}

cnt--; // Decrease records count
}

cnt--; // Decrease records count
return true;
return ret;
}


bool cppQueue::peekIdx(void * const record, const uint16_t idx)
bool __attribute__((nonnull)) cppQueue::peekIdx(void * const record, const uint16_t idx)
{
const uint8_t * pStart;
bool ret = true;

if (idx + 1 > getCount()) { return false; } // Index out of range

if (impl == FIFO)
if ((idx + 1U) > _getCount()) // Index out of range
{
pStart = queue + (rec_sz * ((out + idx) % rec_nb));
ret = false;
}
else if (impl == LIFO)
else
{
pStart = queue + (rec_sz * idx);
const uint8_t * pStart;

if (impl == FIFO)
{
pStart = queue + (rec_sz * ((out + idx) % rec_nb));
}
else /*if (impl == LIFO)*/
{
pStart = queue + (rec_sz * idx);
}

memcpy(record, pStart, rec_sz);
}
else { return false; }

memcpy(record, pStart, rec_sz);
return true;
return ret;
}


bool __attribute__((nonnull)) cppQueue::peekPrevious(void * const record)
{
const uint16_t idx = _getCount() - 1U; // No worry about count - 1 when queue is empty, test is done by peekIdx
return peekIdx(record, idx);
}


/**********************/
/*** PUBLIC GETTERS ***/
/**********************/
bool cppQueue::isInitialized(void) {
return _isInitialized(); }

bool cppQueue::isEmpty(void) {
return _isEmpty(); }

bool cppQueue::isFull(void) {
return _isFull(); }

uint32_t cppQueue::sizeOf(void) {
return queue_sz; }

uint16_t cppQueue::getCount(void) {
return _getCount(); }

uint16_t cppQueue::getRemainingCount(void) {
return rec_nb - cnt; }

Loading

0 comments on commit 9e0faf5

Please sign in to comment.