#pragma once
|
#include <vector>
|
#include <cstdint>
|
#include <algorithm>
|
|
class FrameAssembler {
|
public:
|
// ×·¼ÓÒ»¿éÔʼ×Ö½Ú
|
void push(const std::vector<uint8_t>& chunk) {
|
buf_.insert(buf_.end(), chunk.begin(), chunk.end());
|
}
|
void push(const uint8_t* p, size_t n) {
|
buf_.insert(buf_.end(), p, p + n);
|
}
|
|
// ÌáÈ¡ÏÂÒ»Ö¡£»·µ»Ø true ±íʾ out Äõ½ÁËÒ»Ö¡ÍêÕûÊý¾Ý
|
bool nextFrame(std::vector<uint8_t>& out) {
|
const uint8_t HEAD[4] = { 0x11,0x88,0x11,0x88 };
|
const uint8_t TAIL = 0x88;
|
for (;;) {
|
// ÐèÒªÖÁÉÙ 4B Í· + 4B dataId + 2B len + 1B β = 11B
|
if (buf_.size() < 11) return false;
|
|
// ÕÒͷͬ²½
|
size_t i = 0;
|
while (i + 4 <= buf_.size() && !std::equal(HEAD, HEAD + 4, buf_.begin() + i)) ++i;
|
if (i + 4 > buf_.size()) { // ûÕÒµ½Í·£¬Çå¿Õ
|
buf_.clear();
|
return false;
|
}
|
if (i > 0) buf_.erase(buf_.begin(), buf_.begin() + i); // ¶ªÆúͷǰÔëÉù
|
|
if (buf_.size() < 11) return false; // »¹²»¹»×îС֡
|
|
// ¶ÁÈ¡ÕýÎij¤¶È£¨´ó¶Ë£©
|
uint16_t len = (uint16_t(buf_[8]) << 8) | buf_[9];
|
size_t total = 4 + 4 + 2 + size_t(len) + 1; // ÕûÖ¡³¤¶È
|
if (buf_.size() < total) return false; // °ëÖ¡£¬µÈÏ´Î
|
|
// УÑéβ
|
if (buf_[total - 1] != TAIL) {
|
// β²»¶Ô£º¶ªÆúÒ»¸ö×Ö½Ú£¬ÖØÐÂÕÒÍ·£¨±ÜÃâËÀËø£©
|
buf_.erase(buf_.begin());
|
continue;
|
}
|
|
// È¡³öÍêÕûÖ¡
|
out.assign(buf_.begin(), buf_.begin() + total);
|
buf_.erase(buf_.begin(), buf_.begin() + total);
|
return true;
|
}
|
}
|
|
void clear() { buf_.clear(); }
|
|
private:
|
std::vector<uint8_t> buf_;
|
};
|