File Coverage

src/panda/protocol/websocket/Parser-MessageBuilder.h
Criterion Covered Total %
statement 0 48 0.0
branch 0 54 0.0
condition n/a
subroutine n/a
pod n/a
total 0 102 0.0


line stmt bran cond sub pod time code
1             // this file is included into struct Parser
2             // ! no namespaces here or #includes here !
3              
4             struct MessageBuilder {
5             MessageBuilder (MessageBuilder&&) = default;
6              
7             Opcode opcode () const noexcept { return _opcode; }
8             DeflateFlag deflate () const noexcept { return _deflate; }
9              
10             MessageBuilder& opcode (Opcode v) noexcept { _opcode = v; return *this; }
11             MessageBuilder& deflate (DeflateFlag v) noexcept { _deflate = v; return *this; }
12 0 0         MessageBuilder& deflate (bool v) noexcept { _deflate = v ? DeflateFlag::YES : DeflateFlag::NO; return *this; }
13              
14 0           StringPair send (string& payload) {
15 0           auto apply_deflate = maybe_deflate(payload.length());
16 0 0         return _parser.start_message(_opcode, apply_deflate).send(payload, true);
17             }
18              
19             template ())>::type, string>::value>::type>
20 0           StringChain send (Begin payload_begin, End payload_end) {
21 0           size_t payload_length = 0;
22 0 0         for (auto it = payload_begin; it != payload_end; ++it) payload_length += (*it).length();
23 0           auto apply_deflate = maybe_deflate(payload_length);
24 0 0         return _parser.start_message(_opcode, apply_deflate).send(payload_begin, payload_end, true);
25             }
26              
27             template ::value>::type>
28 0           std::vector send (Begin cont_begin, End cont_end) {
29 0           std::vector ret;
30              
31 0           size_t sz = 0, idx = 0, payload_sz = 0, last_nonempty = 0;
32 0 0         auto cont_range = make_iterator_pair(cont_begin, cont_end);
33              
34 0 0         for (const auto& range : cont_range) {
35 0           size_t piece_sz = 0;
36 0 0         for (const auto& it : range) {
37 0           auto length = it.length();
38 0           piece_sz += length;
39 0 0         if (length) ++sz;
40             }
41 0 0         if (piece_sz) { last_nonempty = idx; };
42 0           payload_sz += piece_sz;
43 0           ++idx;
44             };
45              
46 0 0         auto sender = _parser.start_message(_opcode, maybe_deflate(payload_sz));
    0          
47              
48 0 0         if (!payload_sz) {
49 0 0         ret.reserve(1);
50 0 0         ret.push_back(sender.send(true));
    0          
51 0           return ret;
52             }
53              
54 0 0         ret.reserve(sz);
55              
56 0           idx = 0;
57 0 0         for (auto& range : cont_range) {
58 0           size_t piece_sz = 0;
59 0 0         for (const auto& it: range) piece_sz += it.length();
60 0 0         if (piece_sz) {
61 0 0         auto frame_range = sender.send(range.begin(), range.end(), idx == last_nonempty);
62 0 0         for (const auto& s : frame_range) ret.push_back(s);
    0          
63             }
64 0 0         if (idx == last_nonempty) break;
65 0           ++idx;
66             }
67              
68 0           return ret;
69             }
70              
71             private:
72             friend Parser;
73              
74             Parser& _parser;
75             Opcode _opcode = Opcode::BINARY;
76             DeflateFlag _deflate = DeflateFlag::DEFAULT;
77              
78 0           MessageBuilder (Parser& parser) : _parser(parser) {}
79             MessageBuilder (MessageBuilder&) = delete;
80              
81 0           DeflateFlag maybe_deflate (size_t payload_length) {
82 0           switch (_deflate) {
83 0           case DeflateFlag::NO : return _deflate;
84 0           case DeflateFlag::YES : return _deflate;
85             case DeflateFlag::DEFAULT :
86 0 0         return _opcode == Opcode::TEXT &&
87 0 0         _parser._deflate_cfg &&
88 0 0         _parser._deflate_cfg->compression_threshold <= payload_length &&
89             payload_length > 0
90 0 0         ? DeflateFlag::YES : DeflateFlag::NO;
91             }
92 0           return DeflateFlag::NO;
93             }
94             };