11/* !\file cppQueue.cpp
22** \author SMFSW
3- ** \copyright BSD 3-Clause License (c) 2017-2022 , SMFSW
3+ ** \copyright BSD 3-Clause License (c) 2017-2024 , SMFSW
44** \brief cppQueue handling library (designed on Arduino)
55** \details cppQueue handling library (designed on Arduino)
66** This library was designed for Arduino, yet may be compiled without change with gcc for other purposes/targets
1313/* ***************************************************************/
1414
1515
16+ #define QUEUE_INITIALIZED 0x5AA5U // !< Initialized cppQueue control value
17+
18+
19+ /* *************************/
20+ /* ** INTERNAL FUNCTIONS ***/
21+ /* *************************/
1622/* ! \brief Increment index
1723** \details Increment buffer index \b pIdx rolling back to \b start when limit \b end is reached
1824** \param [in,out] pIdx - pointer to index value
1925** \param [in] end - counter upper limit value
2026** \param [in] start - counter lower limit value
2127**/
22- static inline void __attribute__ ((nonnull, always_inline)) inc_idx (uint16_t * const pIdx, const uint16_t end, const uint16_t start)
28+ static inline void __attribute__ ((nonnull, always_inline)) _inc_idx (uint16_t * const pIdx, const uint16_t end, const uint16_t start)
2329{
24- if (*pIdx < end - 1 ) { (*pIdx)++; }
30+ if (*pIdx < ( end - 1U ) ) { (*pIdx)++; }
2531 else { *pIdx = start; }
2632}
2733
@@ -31,27 +37,62 @@ static inline void __attribute__((nonnull, always_inline)) inc_idx(uint16_t * co
3137** \param [in] end - counter upper limit value
3238** \param [in] start - counter lower limit value
3339**/
34- static inline void __attribute__ ((nonnull, always_inline)) dec_idx (uint16_t * const pIdx, const uint16_t end, const uint16_t start)
40+ static inline void __attribute__ ((nonnull, always_inline)) _dec_idx (uint16_t * const pIdx, const uint16_t end, const uint16_t start)
3541{
3642 if (*pIdx > start) { (*pIdx)--; }
37- else { *pIdx = end - 1 ; }
43+ else { *pIdx = end - 1U ; }
3844}
3945
4046
47+ /* ! \brief get initialization state of the queue
48+ ** \return cppQueue initialization status
49+ ** \retval true if queue is allocated
50+ ** \retval false is queue is not allocated
51+ **/
52+ inline bool __attribute__ ((always_inline)) cppQueue::_isInitialized(void ) {
53+ return (init == QUEUE_INITIALIZED) ? true : false ; }
54+
55+ /* ! \brief get emptiness state of the queue
56+ ** \return cppQueue emptiness status
57+ ** \retval true if queue is empty
58+ ** \retval false is not empty
59+ **/
60+ inline bool __attribute__ ((always_inline)) cppQueue::_isEmpty(void ) {
61+ return (cnt == 0U ) ? true : false ; }
62+
63+ /* ! \brief get fullness state of the queue
64+ ** \return cppQueue fullness status
65+ ** \retval true if queue is full
66+ ** \retval false is not full
67+ **/
68+ inline bool __attribute__ ((always_inline)) cppQueue::_isFull(void ) {
69+ return (cnt == rec_nb) ? true : false ; }
70+
71+
72+ /* ! \brief get number of records in the queue
73+ ** \return Number of records stored in the queue
74+ **/
75+ inline uint16_t __attribute__ ((always_inline)) cppQueue::_getCount(void ) {
76+ return cnt; }
77+
78+
79+ /* ***********************/
80+ /* ** PUBLIC FUNCTIONS ***/
81+ /* ***********************/
4182cppQueue::cppQueue (const size_t size_rec, const uint16_t nb_recs, const cppQueueType type, const bool overwrite, void * const pQDat, const size_t lenQDat)
4283{
4384 init = 0 ;
4485 rec_nb = 0 ; // rec_nb needs to be 0 to ensure proper push behavior when queue is not allocated
4586 ovw = 0 ; // ovw needs to be 0 to ensure proper push behavior when queue is not allocated
4687 flush (); // other variables needs to be 0 to ensure proper functions behavior when queue is not allocated
4788
48- const uint32_t size = nb_recs * size_rec;
89+ const size_t size = nb_recs * size_rec;
4990
5091 dynamic = (pQDat == NULL ) ? true : false ;
5192
5293 if (dynamic) { queue = (uint8_t *) malloc (size); }
53- else if (lenQDat < size) { queue = NULL ; } // Check static Queue data size
54- else { queue = ( uint8_t *) pQDat ; }
94+ else if (lenQDat >= size) { queue = ( uint8_t *) pQDat; }
95+ else { queue = NULL ; }
5596
5697 if (queue != NULL )
5798 {
@@ -67,7 +108,7 @@ cppQueue::cppQueue(const size_t size_rec, const uint16_t nb_recs, const cppQueue
67108
68109cppQueue::~cppQueue ()
69110{
70- if ((init == QUEUE_INITIALIZED ) && dynamic && (queue != NULL )) { free (queue); }
111+ if (_isInitialized ( ) && dynamic && (queue != NULL )) { free (queue); }
71112}
72113
73114
@@ -81,101 +122,179 @@ void cppQueue::flush(void)
81122
82123bool __attribute__ ((nonnull)) cppQueue::push(const void * const record)
83124{
84- if ((!ovw) && isFull ()) { return false ; }
125+ bool ret = true ;
85126
86- uint8_t * const pStart = queue + (rec_sz * in);
87- memcpy (pStart, record, rec_sz);
88-
89- inc_idx (&in, rec_nb, 0 );
127+ if (_isFull ()) // No more records available
128+ {
129+ if (ovw) // cppQueue is full, overwrite is allowed
130+ {
131+ if (impl == FIFO)
132+ {
133+ _inc_idx (&out, rec_nb, 0 ); // as oldest record is overwritten, increment out
134+ }
135+ // else if (impl == LIFO) {} // Nothing to do in this case
136+ }
137+ else
138+ {
139+ ret = false ;
140+ }
141+ }
142+ else
143+ {
144+ cnt++; // Increase records count
145+ }
90146
91- if (!isFull ()) { cnt++; } // Increase records count
92- else if (ovw) // cppQueue is full and overwrite is allowed
147+ if (ret)
93148 {
94- if (impl == FIFO) { inc_idx (&out, rec_nb, 0 ); } // as oldest record is overwritten, increment out
95- // else if (impl == LIFO) {} // Nothing to do in this case
149+ uint8_t * const pStart = queue + (rec_sz * in);
150+ memcpy (pStart, record, rec_sz);
151+ _inc_idx (&in, rec_nb, 0 );
96152 }
97153
98- return true ;
154+ return ret ;
99155}
100156
101157bool __attribute__ ((nonnull)) cppQueue::pop(void * const record)
102158{
103- const uint8_t * pStart;
104-
105- if (isEmpty ()) { return false ; } // No more records
159+ bool ret = true ;
106160
107- if (impl == FIFO)
161+ if (_isEmpty ()) // No records
108162 {
109- pStart = queue + (rec_sz * out);
110- inc_idx (&out, rec_nb, 0 );
163+ ret = false ;
111164 }
112- else if (impl == LIFO)
165+ else
113166 {
114- dec_idx (&in, rec_nb, 0 );
115- pStart = queue + (rec_sz * in);
167+ const uint8_t * pStart;
168+
169+ if (impl == FIFO)
170+ {
171+ pStart = queue + (rec_sz * out);
172+ _inc_idx (&out, rec_nb, 0 );
173+ }
174+ else /* if (impl == LIFO) */
175+ {
176+ _dec_idx (&in, rec_nb, 0 );
177+ pStart = queue + (rec_sz * in);
178+ }
179+
180+ memcpy (record, pStart, rec_sz);
181+ cnt--; // Decrease records count
116182 }
117- else { return false ; }
118183
119- memcpy (record, pStart, rec_sz);
120- cnt--; // Decrease records count
121- return true ;
184+ return ret;
122185}
123186
124187
125188bool __attribute__ ((nonnull)) cppQueue::peek(void * const record)
126189{
127- const uint8_t * pStart ;
190+ bool ret = true ;
128191
129- if (isEmpty ()) { return false ; } // No more records
130-
131- if (impl == FIFO)
192+ if (_isEmpty ()) // No records
132193 {
133- pStart = queue + (rec_sz * out);
134- // No change on out var as it's just a peek
194+ ret = false ;
135195 }
136- else if (impl == LIFO)
196+ else
137197 {
138- uint16_t rec = in; // Temporary var for peek (no change on in with dec_idx)
139- dec_idx (&rec, rec_nb, 0 );
140- pStart = queue + (rec_sz * rec);
198+ const uint8_t * pStart;
199+
200+ if (impl == FIFO)
201+ {
202+ pStart = queue + (rec_sz * out);
203+ // No change on out var as it's just a peek
204+ }
205+ else /* if (impl == LIFO)*/
206+ {
207+ uint16_t rec = in; // Temporary var for peek (no change on in with dec_idx)
208+ _dec_idx (&rec, rec_nb, 0 );
209+ pStart = queue + (rec_sz * rec);
210+ }
211+
212+ memcpy (record, pStart, rec_sz);
141213 }
142- else { return false ; }
143214
144- memcpy (record, pStart, rec_sz);
145- return true ;
215+ return ret;
146216}
147217
148218
149219bool cppQueue::drop (void )
150220{
151- if ( isEmpty ()) { return false ; } // No more records
221+ bool ret = true ;
152222
153- if (impl == FIFO) { inc_idx (&out, rec_nb, 0 ); }
154- else if (impl == LIFO) { dec_idx (&in, rec_nb, 0 ); }
155- else { return false ; }
223+ if (_isEmpty ()) // No records
224+ {
225+ ret = false ;
226+ }
227+ else
228+ {
229+ if (impl == FIFO)
230+ {
231+ _inc_idx (&out, rec_nb, 0 );
232+ }
233+ else /* if (impl == LIFO)*/
234+ {
235+ _dec_idx (&in, rec_nb, 0 );
236+ }
237+
238+ cnt--; // Decrease records count
239+ }
156240
157- cnt--; // Decrease records count
158- return true ;
241+ return ret;
159242}
160243
161244
162- bool cppQueue::peekIdx (void * const record, const uint16_t idx)
245+ bool __attribute__ ((nonnull)) cppQueue::peekIdx(void * const record, const uint16_t idx)
163246{
164- const uint8_t * pStart ;
247+ bool ret = true ;
165248
166- if (idx + 1 > getCount ()) { return false ; } // Index out of range
167-
168- if (impl == FIFO)
249+ if ((idx + 1U ) > _getCount ()) // Index out of range
169250 {
170- pStart = queue + (rec_sz * ((out + idx) % rec_nb)) ;
251+ ret = false ;
171252 }
172- else if (impl == LIFO)
253+ else
173254 {
174- pStart = queue + (rec_sz * idx);
255+ const uint8_t * pStart;
256+
257+ if (impl == FIFO)
258+ {
259+ pStart = queue + (rec_sz * ((out + idx) % rec_nb));
260+ }
261+ else /* if (impl == LIFO)*/
262+ {
263+ pStart = queue + (rec_sz * idx);
264+ }
265+
266+ memcpy (record, pStart, rec_sz);
175267 }
176- else { return false ; }
177268
178- memcpy (record, pStart, rec_sz);
179- return true ;
269+ return ret;
180270}
181271
272+
273+ bool __attribute__ ((nonnull)) cppQueue::peekPrevious(void * const record)
274+ {
275+ const uint16_t idx = _getCount () - 1U ; // No worry about count - 1 when queue is empty, test is done by peekIdx
276+ return peekIdx (record, idx);
277+ }
278+
279+
280+ /* *********************/
281+ /* ** PUBLIC GETTERS ***/
282+ /* *********************/
283+ bool cppQueue::isInitialized (void ) {
284+ return _isInitialized (); }
285+
286+ bool cppQueue::isEmpty (void ) {
287+ return _isEmpty (); }
288+
289+ bool cppQueue::isFull (void ) {
290+ return _isFull (); }
291+
292+ uint32_t cppQueue::sizeOf (void ) {
293+ return queue_sz; }
294+
295+ uint16_t cppQueue::getCount (void ) {
296+ return _getCount (); }
297+
298+ uint16_t cppQueue::getRemainingCount (void ) {
299+ return rec_nb - cnt; }
300+
0 commit comments