libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
chunk_queue.hpp
1#pragma once
2
3#include <cstddef>
4
5#include "libxr_def.hpp"
6#include "mutex.hpp"
7#include "queue.hpp"
8
9namespace LibXR
10{
22{
23 public:
25
33 : block_queue_(sizeof(BlockInfo), max_blocks),
34 data_queue_(1, data_buffer_size),
35 max_blocks_(max_blocks)
36 {
38 }
39
45 ErrorCode CreateNewBlock()
46 {
48 return CreateNewBlockNoLock();
49 }
50
56 ErrorCode AppendToCurrentBlock(const void *data, size_t size)
57 {
59 return AppendToCurrentBlockNoLock(data, size);
60 }
61
69 ErrorCode Pop(size_t size, void *data = nullptr)
70 {
72
73 return PopNoLock(size, data);
74 }
75
84 ErrorCode PopFromCallback(size_t size, void *data, bool in_isr)
85 {
87
88 if (!lock_guard.Locked())
89 {
90 return ErrorCode::TIMEOUT;
91 }
92
93 return PopNoLock(size, data);
94 }
95
103 ErrorCode PopBlock(void *buffer, size_t *out_size)
104 {
106
107 return PopBlockNoLock(buffer, out_size);
108 }
109
118 ErrorCode PopBlockFromCallback(void *buffer, size_t *out_size, bool in_isr)
119 {
121
122 if (!lock_guard.Locked())
123 {
124 return ErrorCode::TIMEOUT;
125 }
126
127 return PopBlockNoLock(buffer, out_size);
128 }
129
134 void Reset()
135 {
136 block_queue_.Reset();
137 data_queue_.Reset();
138 }
139
145 size_t Size()
146 {
148
149 return data_queue_.Size();
150 }
151
158 size_t BlockSize()
159 {
161
162 return block_queue_.Size();
163 }
164
172 {
174
175 if (!lock_guard.Locked())
176 {
177 return 0;
178 }
179
180 return data_queue_.Size();
181 }
182
191 {
193
194 if (!lock_guard.Locked())
195 {
196 return 0;
197 }
198
199 return block_queue_.Size();
200 }
201
216 size_t EmptySize()
217 {
219
220 if (block_queue_.EmptySize() > 0)
221 {
222 return data_queue_.EmptySize();
223 }
224 else
225 {
226 return 0;
227 }
228 }
229
237 {
239 return block_queue_.EmptySize();
240 }
241
259 {
261
262 if (!lock_guard.Locked())
263 {
264 return 0;
265 }
266
267 if (block_queue_.EmptySize() > 0)
268 {
269 return data_queue_.EmptySize();
270 }
271 else
272 {
273 return 0;
274 }
275 }
276
286 {
288
289 if (!lock_guard.Locked())
290 {
291 return 0;
292 }
293
294 return block_queue_.EmptySize();
295 }
296
297 ChunkQueue(const ChunkQueue &) = delete;
298 ChunkQueue operator=(const ChunkQueue &) = delete;
299 ChunkQueue operator=(ChunkQueue &) = delete;
300 ChunkQueue operator=(const ChunkQueue &&) = delete;
301 ChunkQueue operator=(ChunkQueue &&) = delete;
302
303 private:
304 ErrorCode CreateNewBlockNoLock()
305 {
306 auto index = block_queue_.GetLastElementIndex();
307
308 if (index >= 0)
309 {
310 BlockInfo *last_block = reinterpret_cast<BlockInfo *>(block_queue_[index]);
311 if (*last_block == 0)
312 {
313 return ErrorCode::OK;
314 }
315 }
316
317 if (block_queue_.Size() >= max_blocks_)
318 {
319 return ErrorCode::FULL;
320 }
322 return block_queue_.Push(&new_block);
323 }
324
325 ErrorCode AppendToCurrentBlockNoLock(const void *data, size_t size)
326 {
327 if (!data)
328 {
329 return ErrorCode::PTR_NULL;
330 }
331 if (size == 0)
332 {
333 return ErrorCode::ARG_ERR;
334 }
335
336 if (block_queue_.Size() == 0)
337 {
338 if (CreateNewBlockNoLock() != ErrorCode::OK)
339 {
340 return ErrorCode::FULL;
341 }
342 }
343
344 auto index = block_queue_.GetLastElementIndex();
345
346 BlockInfo *last_block = static_cast<BlockInfo *>(block_queue_[index]);
347
348 if (size > data_queue_.EmptySize())
349 {
350 return ErrorCode::NO_BUFF;
351 }
352
353 if (data_queue_.PushBatch(reinterpret_cast<const uint8_t *>(data), size) !=
354 ErrorCode::OK)
355 {
356 return ErrorCode::FULL;
357 }
358
359 *last_block += size;
360 return ErrorCode::OK;
361 }
362
363 ErrorCode PopNoLock(size_t size, void *data = nullptr)
364 {
365 if (data_queue_.Size() < size)
366 {
367 return ErrorCode::EMPTY;
368 }
369
370 size_t remaining_size = size;
371
372 while (remaining_size > 0)
373 {
374 auto index = block_queue_.GetFirstElementIndex();
375 if (index < 0)
376 {
377 return ErrorCode::CHECK_ERR;
378 }
379
380 BlockInfo *block = static_cast<BlockInfo *>(block_queue_[index]);
381
382 if (remaining_size < *block)
383 {
384 if (data_queue_.PopBatch(data, remaining_size) != ErrorCode::OK)
385 {
386 ASSERT(false);
387 return ErrorCode::CHECK_ERR;
388 }
389
391 remaining_size = 0;
392 }
393 else
394 {
395 if (data_queue_.PopBatch(data, *block) != ErrorCode::OK)
396 {
397 ASSERT(false);
398 return ErrorCode::CHECK_ERR;
399 }
401 data = static_cast<uint8_t *>(data) + *block;
402 block_queue_.Pop();
403 }
404 }
405
406 return ErrorCode::OK;
407 }
408
409 ErrorCode PopBlockNoLock(void *buffer, size_t *out_size)
410 {
411 auto index = block_queue_.GetFirstElementIndex();
412
413 if (index >= 0)
414 {
415 BlockInfo *last_block = static_cast<BlockInfo *>(block_queue_[index]);
416 if (*last_block == 0)
417 {
418 return ErrorCode::EMPTY;
419 }
420 }
421 else
422 {
423 return ErrorCode::EMPTY;
424 }
425
426 BlockInfo block; // NOLINT
427 if (block_queue_.Pop(&block) != ErrorCode::OK)
428 {
429 ASSERT(false);
430 return ErrorCode::EMPTY;
431 }
432
433 if (data_queue_.PopBatch(buffer, block) != ErrorCode::OK)
434 {
435 ASSERT(false);
436 return ErrorCode::CHECK_ERR;
437 }
438 *out_size = block;
439 return ErrorCode::OK;
440 }
441
442 BaseQueue block_queue_;
443 BaseQueue data_queue_;
444 size_t max_blocks_;
445 Mutex mutex_;
446};
447} // namespace LibXR
ErrorCode Pop(void *data=nullptr)
移除队列头部的元素 (Pop the front element from the queue).
Definition queue.hpp:114
ErrorCode Push(const void *data)
向队列中添加一个元素 (Push an element into the queue).
Definition queue.hpp:66
size_t Size()
获取队列中的元素个数 (Get the number of elements in the queue).
Definition queue.hpp:305
ErrorCode PopBatch(void *data, size_t size)
批量移除多个元素 (Pop multiple elements from the queue).
Definition queue.hpp:208
void Reset()
重置队列,清空所有数据 (Reset the queue and clear all data).
Definition queue.hpp:295
int GetFirstElementIndex()
获取队列中第一个元素的索引 (Get the index of the first element in the queue).
Definition queue.hpp:156
size_t EmptySize()
获取队列的空闲空间 (Get the available space in the queue).
Definition queue.hpp:325
ErrorCode PushBatch(const void *data, size_t size)
批量推入多个元素 (Push multiple elements into the queue).
Definition queue.hpp:175
int GetLastElementIndex()
获取队列中最后一个元素的索引 (Get the index of the last element in the queue).
Definition queue.hpp:138
块队列(ChunkQueue)用于存储和管理数据块 ChunkQueue is used to store and manage chunks of data
size_t BlockSize()
获取当前数据块数量 Gets the current number of data blocks
size_t SizeFromCallback(bool in_isr)
从 ISR 中获取当前数据大小 Gets the current data size from an ISR
ErrorCode AppendToCurrentBlock(const void *data, size_t size)
创建一个新的数据块(线程安全) Creates a new data block (thread-safe)
size_t EmptySize()
获取队列的剩余可用空间(线程安全) Gets the remaining available space in the queue (thread-safe)
size_t EmptyBlockSizeFromCallback(bool in_isr)
从 ISR(中断服务例程)中获取块信息的剩余可用空间 Gets the remaining available space in the block information from an ISR (I...
ErrorCode CreateNewBlock()
创建一个新的数据块(线程安全) Creates a new data block (thread-safe)
ErrorCode PopBlockFromCallback(void *buffer, size_t *out_size, bool in_isr)
从回调函数(ISR)中弹出整个数据块 Pops an entire data block from an ISR
ErrorCode PopFromCallback(size_t size, void *data, bool in_isr)
从回调函数(ISR)中弹出数据 Pops data from an ISR (Interrupt Service Routine)
ErrorCode Pop(size_t size, void *data=nullptr)
弹出指定大小的数据(线程安全) Pops the specified size of data (thread-safe)
size_t EmptySizeFromCallback(bool in_isr)
从 ISR(中断服务例程)中获取队列的剩余可用空间 Gets the remaining available space in the queue from an ISR (Interrupt Serv...
size_t Size()
获取当前数据大小 Gets the current size of the data
ChunkQueue(size_t max_blocks, size_t data_buffer_size)
构造一个块队列 Constructs a chunk queue
size_t BlockSizeFromCallback(bool in_isr)
从 ISR 中获取当前数据块数量 Gets the current number of data blocks from an ISR
size_t EmptyBlockSize()
获取块信息的剩余可用空间(线程安全) Gets the remaining available space in the block information (thread-safe)
void Reset()
重置队列 Resets the queue
uint32_t BlockInfo
记录块信息的类型 Type for storing block information
ErrorCode PopBlock(void *buffer, size_t *out_size)
弹出整个数据块(线程安全) Pops an entire data block (thread-safe)
互斥锁的 RAII 机制封装 (RAII-style mechanism for automatic mutex management).
Definition mutex.hpp:95
回调(ISR)上下文中的互斥锁管理类 (Lock management class for ISR context).
Definition mutex.hpp:123
LibXR Color Control Library / LibXR终端颜色控制库
constexpr auto min(T1 a, T2 b) -> typename std::common_type< T1, T2 >::type
计算两个数的最小值