chenluhua1980
2025-12-11 5e9b9b53a8a853365c29149871bd024c9ca0cbac
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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_;
};