* @brief Extracts frames bounded by matching start and end delimiters. */
| 480 | * @brief Extracts frames bounded by matching start and end delimiters. |
| 481 | */ |
| 482 | void IO::FrameReader::readStartEndDelimitedFrames() |
| 483 | { |
| 484 | Q_ASSERT(!m_startSequences.isEmpty()); |
| 485 | Q_ASSERT(!m_startSequenceLps.isEmpty()); |
| 486 | Q_ASSERT(!m_finishSequences.isEmpty()); |
| 487 | Q_ASSERT(!m_finishSequenceLps.isEmpty()); |
| 488 | |
| 489 | const auto& startSeq = m_startSequences[0]; |
| 490 | const auto& startLps = m_startSequenceLps[0]; |
| 491 | const auto& finishSeq = m_finishSequences[0]; |
| 492 | const auto& finishLps = m_finishSequenceLps[0]; |
| 493 | |
| 494 | constexpr int kMaxFramesPerCall = 32768; |
| 495 | int iterations = 0; |
| 496 | while (iterations < kMaxFramesPerCall) { |
| 497 | ++iterations; |
| 498 | |
| 499 | int finishIndex = m_circularBuffer.findPatternKMP(finishSeq, finishLps); |
| 500 | if (finishIndex == -1) |
| 501 | break; |
| 502 | |
| 503 | int startIndex = m_circularBuffer.findPatternKMP(startSeq, startLps); |
| 504 | if (startIndex == -1 || startIndex >= finishIndex) { |
| 505 | consumeBytes(finishIndex + finishSeq.size()); |
| 506 | continue; |
| 507 | } |
| 508 | |
| 509 | qsizetype frameStart = startIndex + startSeq.size(); |
| 510 | qsizetype frameLength = finishIndex - frameStart; |
| 511 | if (frameLength <= 0) { |
| 512 | consumeBytes(finishIndex + finishSeq.size()); |
| 513 | continue; |
| 514 | } |
| 515 | |
| 516 | const auto crcPosition = finishIndex + finishSeq.size(); |
| 517 | const auto frameEndPos = crcPosition + m_checksumLength; |
| 518 | |
| 519 | CapturedDataPtr ptr; |
| 520 | CapturedData* cd = claimCapturedSlot(ptr); |
| 521 | m_circularBuffer.peekRangeInto(frameStart, frameLength, cd->data); |
| 522 | if (cd->data.isEmpty()) { |
| 523 | consumeBytes(frameEndPos); |
| 524 | continue; |
| 525 | } |
| 526 | |
| 527 | const auto result = checksum(cd->data, crcPosition); |
| 528 | if (result == ValidationStatus::ChecksumIncomplete) |
| 529 | break; |
| 530 | |
| 531 | if (result == ValidationStatus::FrameOk) |
| 532 | enqueueCaptured(std::move(ptr), cd, frameEndPos); |
| 533 | else |
| 534 | consumeBytes(frameEndPos); |
| 535 | } |
| 536 | |
| 537 | if (iterations >= kMaxFramesPerCall) [[unlikely]] |
| 538 | qWarning() << "[FrameReader] Loop iteration limit reached in readStartEndDelimitedFrames"; |
| 539 | } |
nothing calls this directly
no test coverage detected