1
1
/* !\file cppQueue.cpp
2
2
** \author SMFSW
3
- ** \copyright BSD 3-Clause License (c) 2017-2022 , SMFSW
3
+ ** \copyright BSD 3-Clause License (c) 2017-2024 , SMFSW
4
4
** \brief cppQueue handling library (designed on Arduino)
5
5
** \details cppQueue handling library (designed on Arduino)
6
6
** This library was designed for Arduino, yet may be compiled without change with gcc for other purposes/targets
13
13
/* ***************************************************************/
14
14
15
15
16
+ #define QUEUE_INITIALIZED 0x5AA5U // !< Initialized cppQueue control value
17
+
18
+
19
+ /* *************************/
20
+ /* ** INTERNAL FUNCTIONS ***/
21
+ /* *************************/
16
22
/* ! \brief Increment index
17
23
** \details Increment buffer index \b pIdx rolling back to \b start when limit \b end is reached
18
24
** \param [in,out] pIdx - pointer to index value
19
25
** \param [in] end - counter upper limit value
20
26
** \param [in] start - counter lower limit value
21
27
**/
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)
23
29
{
24
- if (*pIdx < end - 1 ) { (*pIdx)++; }
30
+ if (*pIdx < ( end - 1U ) ) { (*pIdx)++; }
25
31
else { *pIdx = start; }
26
32
}
27
33
@@ -31,27 +37,62 @@ static inline void __attribute__((nonnull, always_inline)) inc_idx(uint16_t * co
31
37
** \param [in] end - counter upper limit value
32
38
** \param [in] start - counter lower limit value
33
39
**/
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)
35
41
{
36
42
if (*pIdx > start) { (*pIdx)--; }
37
- else { *pIdx = end - 1 ; }
43
+ else { *pIdx = end - 1U ; }
38
44
}
39
45
40
46
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
+ /* ***********************/
41
82
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)
42
83
{
43
84
init = 0 ;
44
85
rec_nb = 0 ; // rec_nb needs to be 0 to ensure proper push behavior when queue is not allocated
45
86
ovw = 0 ; // ovw needs to be 0 to ensure proper push behavior when queue is not allocated
46
87
flush (); // other variables needs to be 0 to ensure proper functions behavior when queue is not allocated
47
88
48
- const uint32_t size = nb_recs * size_rec;
89
+ const size_t size = nb_recs * size_rec;
49
90
50
91
dynamic = (pQDat == NULL ) ? true : false ;
51
92
52
93
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 ; }
55
96
56
97
if (queue != NULL )
57
98
{
@@ -67,7 +108,7 @@ cppQueue::cppQueue(const size_t size_rec, const uint16_t nb_recs, const cppQueue
67
108
68
109
cppQueue::~cppQueue ()
69
110
{
70
- if ((init == QUEUE_INITIALIZED ) && dynamic && (queue != NULL )) { free (queue); }
111
+ if (_isInitialized ( ) && dynamic && (queue != NULL )) { free (queue); }
71
112
}
72
113
73
114
@@ -81,101 +122,179 @@ void cppQueue::flush(void)
81
122
82
123
bool __attribute__ ((nonnull)) cppQueue::push(const void * const record)
83
124
{
84
- if ((!ovw) && isFull ()) { return false ; }
125
+ bool ret = true ;
85
126
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
+ }
90
146
91
- if (!isFull ()) { cnt++; } // Increase records count
92
- else if (ovw) // cppQueue is full and overwrite is allowed
147
+ if (ret)
93
148
{
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 );
96
152
}
97
153
98
- return true ;
154
+ return ret ;
99
155
}
100
156
101
157
bool __attribute__ ((nonnull)) cppQueue::pop(void * const record)
102
158
{
103
- const uint8_t * pStart;
104
-
105
- if (isEmpty ()) { return false ; } // No more records
159
+ bool ret = true ;
106
160
107
- if (impl == FIFO)
161
+ if (_isEmpty ()) // No records
108
162
{
109
- pStart = queue + (rec_sz * out);
110
- inc_idx (&out, rec_nb, 0 );
163
+ ret = false ;
111
164
}
112
- else if (impl == LIFO)
165
+ else
113
166
{
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
116
182
}
117
- else { return false ; }
118
183
119
- memcpy (record, pStart, rec_sz);
120
- cnt--; // Decrease records count
121
- return true ;
184
+ return ret;
122
185
}
123
186
124
187
125
188
bool __attribute__ ((nonnull)) cppQueue::peek(void * const record)
126
189
{
127
- const uint8_t * pStart ;
190
+ bool ret = true ;
128
191
129
- if (isEmpty ()) { return false ; } // No more records
130
-
131
- if (impl == FIFO)
192
+ if (_isEmpty ()) // No records
132
193
{
133
- pStart = queue + (rec_sz * out);
134
- // No change on out var as it's just a peek
194
+ ret = false ;
135
195
}
136
- else if (impl == LIFO)
196
+ else
137
197
{
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);
141
213
}
142
- else { return false ; }
143
214
144
- memcpy (record, pStart, rec_sz);
145
- return true ;
215
+ return ret;
146
216
}
147
217
148
218
149
219
bool cppQueue::drop (void )
150
220
{
151
- if ( isEmpty ()) { return false ; } // No more records
221
+ bool ret = true ;
152
222
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
+ }
156
240
157
- cnt--; // Decrease records count
158
- return true ;
241
+ return ret;
159
242
}
160
243
161
244
162
- bool cppQueue::peekIdx (void * const record, const uint16_t idx)
245
+ bool __attribute__ ((nonnull)) cppQueue::peekIdx(void * const record, const uint16_t idx)
163
246
{
164
- const uint8_t * pStart ;
247
+ bool ret = true ;
165
248
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
169
250
{
170
- pStart = queue + (rec_sz * ((out + idx) % rec_nb)) ;
251
+ ret = false ;
171
252
}
172
- else if (impl == LIFO)
253
+ else
173
254
{
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);
175
267
}
176
- else { return false ; }
177
268
178
- memcpy (record, pStart, rec_sz);
179
- return true ;
269
+ return ret;
180
270
}
181
271
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