File Coverage

src/panda/protocol/websocket/Frame.h
Criterion Covered Total %
statement 2 3 66.6
branch n/a
condition n/a
subroutine n/a
pod n/a
total 2 3 66.6


line stmt bran cond sub pod time code
1             #pragma once
2             #include "inc.h"
3             #include "utils.h"
4             #include "Error.h"
5             #include "FrameHeader.h"
6             #include
7             #include
8             #include
9             #include
10             #include
11             #include
12              
13             namespace panda { namespace protocol { namespace websocket {
14              
15             using panda::string;
16              
17             struct Frame : virtual panda::Refcnt, AllocatedObject {
18             static constexpr int MAX_CONTROL_PAYLOAD = 125;
19             static constexpr int MAX_CLOSE_PAYLOAD = MAX_CONTROL_PAYLOAD - 2;
20              
21             ErrorCode error;
22             std::vector payload;
23              
24             Frame (bool mask_required, size_t max_size) : _mask_required(mask_required), _max_size(max_size), _state(State::HEADER) {}
25              
26 2434           bool is_control () const { return _header.is_control(); }
27 4180           Opcode opcode () const { return _header.opcode; }
28 0           bool final () const { return _header.fin; }
29             bool rsv1 () const { return _header.rsv1; }
30             bool rsv2 () const { return _header.rsv2; }
31             bool rsv3 () const { return _header.rsv3; }
32             size_t payload_length () const { return _header.length; }
33             uint16_t close_code () const { return _close_code; }
34             string close_message () const { return _close_message; }
35              
36             size_t max_size () const { return _max_size; }
37             void max_size (size_t newsize) { _max_size = newsize; }
38              
39             bool parse (string& buf);
40              
41             void reset () {
42             _state = State::HEADER;
43             _header.reset();
44             error.clear();
45             payload.clear();
46             }
47              
48             static string compile (const FrameHeader& header) {
49             return header.compile(0);
50             }
51              
52             static string compile (const FrameHeader& header, string& payload) {
53             size_t plen = payload.length();
54             if (header.has_mask && plen) crypt_mask(payload.buf(), plen, header.mask, 0);
55             return header.compile(plen);
56             }
57              
58             template
59             static string compile (const FrameHeader& header, It payload_begin, It payload_end) {
60             size_t plen = 0;
61             auto payload = IteratorPair(payload_begin, payload_end);
62             if (header.has_mask) for (string& str : payload) {
63             auto slen = str.length();
64             crypt_mask(str.buf(), slen, header.mask, plen);
65             plen += slen;
66             }
67             else for (string& str : payload) plen += str.length();
68              
69             return header.compile(plen);
70             }
71              
72             private:
73             enum class State { HEADER, PAYLOAD, DONE };
74             bool _mask_required;
75             size_t _max_size;
76             State _state;
77             FrameHeader _header;
78             uint64_t _payload_bytes_left;
79             uint16_t _close_code;
80             string _close_message;
81              
82             };
83              
84             using FrameSP = panda::iptr;
85              
86             }}}