一个在数据流中解析、提取数据帧的c++类

工作中经常遇到需要在数据流中提取数据帧的任务。这种数据帧一般以某种特定数据序列表示开始(例如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

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月14日 下午4:06
下一篇 2023年2月14日 下午4:06

相关推荐