工作中经常遇到需要在数据流中提取数据帧的任务。这种数据帧一般以某种特定数据序列表示开始(例如0xa5,0x5a)和结束(0xb5, 0x5b),起始标记间的数据为帧有效数据。为了完成这一任务,包装了一个简易的解析类,在性能要求不高场合使用。
2019-08-02升级:
可以用参数 discardTag 控制在解析数据帧时是否带起始、结束标记数据
解析类代码如下
1 #ifndef FRAMEPARSER_H
2 #define FRAMEPARSER_H
3
4 #include <vector>
5 #include <algorithm>
6 #include <iterator>
7
8 template <typename T>
9 class FrameParser
10 {
11 public:
12 FrameParser(const std::vector<T> &headTag, const std::vector<T> &tailTag, const bool discardTag=true)
13 : frameHeadTag(headTag), frameTailTag(tailTag), discardFrameTag{ discardTag }
14 {}
15
16 bool isDiscardFrameTag() const {
17 return discardFrameTag;
18 }
19
20 template<class It>
21 void append(It f, It l) {
22 buffer.insert(buffer.end(), f, l);
23 }
24 void append(const std::vector<T> &data) {
25 buffer.insert(buffer.end(), data.cbegin(), data.cend());
26 }
27
28 void parse(std::vector<std::vector<T>>& frames)
29 {
30 auto it_head{ buffer.cbegin() };
31 for (auto it_tail{ std::search(it_head, buffer.cend(), frameTailTag.cbegin(), frameTailTag.cend()) };
32 it_tail != buffer.cend(); it_tail = std::search(it_head, buffer.cend(), frameTailTag.cbegin(), frameTailTag.cend()))
33 {
34 it_head = std::search(it_head, it_tail, frameHeadTag.cbegin(), frameHeadTag.cend());
35 if (it_head != it_tail) {
36 frames.emplace_back(isDiscardFrameTag() ? it_head + frameHeadTag.size() : it_head
37 , isDiscardFrameTag() ? it_tail : it_tail + frameTailTag.size());
38 }
39 it_head = std::next(it_tail, frameTailTag.size());
40 }
41
42 tempBuffer.insert(tempBuffer.end(), it_head, buffer.cend());
43 std::swap(buffer, tempBuffer);
44 tempBuffer.clear();
45 }
46
47 private:
48 bool discardFrameTag{ true };
49 const std::vector<T> frameHeadTag;
50 const std::vector<T> frameTailTag;
51 std::vector<T> buffer;
52 std::vector<T> tempBuffer;
53 };
54
55 #endif // FRAMEPARSER_H
使用测试代码如下
1 FrameParser<std::uint8_t> parser{{ 0xa5, 0x5a }, { 0xb5, 0x5b }};
2 std::vector<std::vector<std::uint8_t>> frames;
3
4 parser.append({
5 0x01, 0x02, 0x03, 0xb5, 0x5b
6 , 0xa5, 0x5a, 0x04, 0x05, 0x06, 0x07, 0xb5, 0x5b
7 , 0xa5, 0x5a, 0x08, 0x09, 0x0a
8 });
9 parser.parse(frames);
10
11 parser.append({ 0x0b, 0xb5, 0x5b, 0xa5, 0x5a, 0x0c });
12 parser.parse(frames);
13
14 parser.append({ 0x0b, 0xb5 });
15 parser.parse(frames);
原文链接: https://www.cnblogs.com/thinkway/p/7874086.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/263824
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!