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