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
|
|
|
|
|
|
|
}; |