Coverage Report

Created: 2025-12-05 06:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/uWebSockets/src/WebSocketProtocol.h
Line
Count
Source
1
/*
2
 * Authored by Alex Hultman, 2018-2020.
3
 * Intellectual property of third-party.
4
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
9
 *     http://www.apache.org/licenses/LICENSE-2.0
10
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
#ifndef UWS_WEBSOCKETPROTOCOL_H
19
#define UWS_WEBSOCKETPROTOCOL_H
20
21
#include <libusockets.h>
22
23
#include <cstdint>
24
#include <cstring>
25
#include <cstdlib>
26
#include <string_view>
27
28
#ifdef UWS_USE_SIMDUTF
29
  #include <simdutf.h>
30
#endif
31
32
namespace uWS {
33
34
/* We should not overcomplicate these */
35
constexpr std::string_view ERR_TOO_BIG_MESSAGE("Received too big message");
36
constexpr std::string_view ERR_WEBSOCKET_TIMEOUT("WebSocket timed out from inactivity");
37
constexpr std::string_view ERR_INVALID_TEXT("Received invalid UTF-8");
38
constexpr std::string_view ERR_TOO_BIG_MESSAGE_INFLATION("Received too big message, or other inflation error");
39
constexpr std::string_view ERR_INVALID_CLOSE_PAYLOAD("Received invalid close payload");
40
constexpr std::string_view ERR_PROTOCOL("Received invalid WebSocket frame");
41
constexpr std::string_view ERR_TCP_FIN("Received TCP FIN before WebSocket close frame");
42
43
enum OpCode : unsigned char {
44
    CONTINUATION = 0,
45
    TEXT = 1,
46
    BINARY = 2,
47
    CLOSE = 8,
48
    PING = 9,
49
    PONG = 10
50
};
51
52
enum {
53
    CLIENT,
54
    SERVER
55
};
56
57
// 24 bytes perfectly
58
template <bool isServer>
59
struct WebSocketState {
60
public:
61
    static const unsigned int SHORT_MESSAGE_HEADER = isServer ? 6 : 2;
62
    static const unsigned int MEDIUM_MESSAGE_HEADER = isServer ? 8 : 4;
63
    static const unsigned int LONG_MESSAGE_HEADER = isServer ? 14 : 10;
64
65
    // 16 bytes
66
    struct State {
67
        unsigned int wantsHead : 1;
68
        unsigned int spillLength : 4;
69
        signed int opStack : 2; // -1, 0, 1
70
        unsigned int lastFin : 1;
71
72
        // 15 bytes
73
        unsigned char spill[LONG_MESSAGE_HEADER - 1];
74
        OpCode opCode[2];
75
76
362k
        State() {
77
362k
            wantsHead = true;
78
362k
            spillLength = 0;
79
362k
            opStack = -1;
80
362k
            lastFin = true;
81
362k
        }
82
83
    } state;
84
85
    // 8 bytes
86
    unsigned int remainingBytes = 0;
87
    char mask[isServer ? 4 : 1];
88
};
89
90
namespace protocol {
91
92
template <typename T>
93
40.8k
T bit_cast(char *c) {
94
40.8k
    T val;
95
40.8k
    memcpy(&val, c, sizeof(T));
96
40.8k
    return val;
97
40.8k
}
unsigned short uWS::protocol::bit_cast<unsigned short>(char*)
Line
Count
Source
93
24.5k
T bit_cast(char *c) {
94
24.5k
    T val;
95
24.5k
    memcpy(&val, c, sizeof(T));
96
24.5k
    return val;
97
24.5k
}
unsigned long uWS::protocol::bit_cast<unsigned long>(char*)
Line
Count
Source
93
16.2k
T bit_cast(char *c) {
94
16.2k
    T val;
95
16.2k
    memcpy(&val, c, sizeof(T));
96
16.2k
    return val;
97
16.2k
}
98
99
/* Byte swap for little-endian systems */
100
template <typename T>
101
110k
T cond_byte_swap(T value) {
102
110k
    static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable");
103
110k
    uint32_t endian_test = 1;
104
110k
    if (*reinterpret_cast<char*>(&endian_test)) {
105
110k
        uint8_t src[sizeof(T)];
106
110k
        uint8_t dst[sizeof(T)];
107
108
110k
        std::memcpy(src, &value, sizeof(T));
109
428k
        for (size_t i = 0; i < sizeof(T); ++i) {
110
318k
            dst[i] = src[sizeof(T) - 1 - i];
111
318k
        }
112
113
110k
        T result;
114
110k
        std::memcpy(&result, dst, sizeof(T));
115
110k
        return result;
116
110k
    }
117
0
    return value;
118
110k
}
unsigned short uWS::protocol::cond_byte_swap<unsigned short>(unsigned short)
Line
Count
Source
101
93.9k
T cond_byte_swap(T value) {
102
93.9k
    static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable");
103
93.9k
    uint32_t endian_test = 1;
104
93.9k
    if (*reinterpret_cast<char*>(&endian_test)) {
105
93.9k
        uint8_t src[sizeof(T)];
106
93.9k
        uint8_t dst[sizeof(T)];
107
108
93.9k
        std::memcpy(src, &value, sizeof(T));
109
281k
        for (size_t i = 0; i < sizeof(T); ++i) {
110
187k
            dst[i] = src[sizeof(T) - 1 - i];
111
187k
        }
112
113
93.9k
        T result;
114
93.9k
        std::memcpy(&result, dst, sizeof(T));
115
93.9k
        return result;
116
93.9k
    }
117
0
    return value;
118
93.9k
}
unsigned long uWS::protocol::cond_byte_swap<unsigned long>(unsigned long)
Line
Count
Source
101
16.2k
T cond_byte_swap(T value) {
102
16.2k
    static_assert(std::is_trivially_copyable<T>::value, "T must be trivially copyable");
103
16.2k
    uint32_t endian_test = 1;
104
16.2k
    if (*reinterpret_cast<char*>(&endian_test)) {
105
16.2k
        uint8_t src[sizeof(T)];
106
16.2k
        uint8_t dst[sizeof(T)];
107
108
16.2k
        std::memcpy(src, &value, sizeof(T));
109
146k
        for (size_t i = 0; i < sizeof(T); ++i) {
110
130k
            dst[i] = src[sizeof(T) - 1 - i];
111
130k
        }
112
113
16.2k
        T result;
114
16.2k
        std::memcpy(&result, dst, sizeof(T));
115
16.2k
        return result;
116
16.2k
    }
117
0
    return value;
118
16.2k
}
119
120
#ifdef UWS_USE_SIMDUTF
121
122
static bool isValidUtf8(unsigned char *s, size_t length)
123
{
124
    return simdutf::validate_utf8((const char *)s, length);
125
}
126
127
#else
128
// Based on utf8_check.c by Markus Kuhn, 2005
129
// https://www.cl.cam.ac.uk/~mgk25/ucs/utf8_check.c
130
// Optimized for predominantly 7-bit content by Alex Hultman, 2016
131
// Licensed as Zlib, like the rest of this project
132
// This runs about 40% faster than simdutf with g++ -mavx
133
static bool isValidUtf8(unsigned char *s, size_t length)
134
1.14M
{
135
1.17M
    for (unsigned char *e = s + length; s != e; ) {
136
1.15M
        if (s + 16 <= e) {
137
28.0k
            uint64_t tmp[2];
138
28.0k
            memcpy(tmp, s, 16);
139
28.0k
            if (((tmp[0] & 0x8080808080808080) | (tmp[1] & 0x8080808080808080)) == 0) {
140
13.5k
                s += 16;
141
13.5k
                continue;
142
13.5k
            }
143
28.0k
        }
144
145
1.74M
        while (!(*s & 0x80)) {
146
1.69M
            if (++s == e) {
147
1.08M
                return true;
148
1.08M
            }
149
1.69M
        }
150
151
53.6k
        if ((s[0] & 0x60) == 0x40) {
152
9.28k
            if (s + 1 >= e || (s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) {
153
5.74k
                return false;
154
5.74k
            }
155
3.53k
            s += 2;
156
44.3k
        } else if ((s[0] & 0xf0) == 0xe0) {
157
9.30k
            if (s + 2 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
158
5.99k
                    (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || (s[0] == 0xed && (s[1] & 0xe0) == 0xa0)) {
159
5.99k
                return false;
160
5.99k
            }
161
3.31k
            s += 3;
162
35.0k
        } else if ((s[0] & 0xf8) == 0xf0) {
163
23.1k
            if (s + 3 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
164
19.7k
                    (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) {
165
19.7k
                return false;
166
19.7k
            }
167
3.39k
            s += 4;
168
11.8k
        } else {
169
11.8k
            return false;
170
11.8k
        }
171
53.6k
    }
172
20.6k
    return true;
173
1.14M
}
WebSocket.cpp:uWS::protocol::isValidUtf8(unsigned char*, unsigned long)
Line
Count
Source
134
27.0k
{
135
29.6k
    for (unsigned char *e = s + length; s != e; ) {
136
23.6k
        if (s + 16 <= e) {
137
7.23k
            uint64_t tmp[2];
138
7.23k
            memcpy(tmp, s, 16);
139
7.23k
            if (((tmp[0] & 0x8080808080808080) | (tmp[1] & 0x8080808080808080)) == 0) {
140
359
                s += 16;
141
359
                continue;
142
359
            }
143
7.23k
        }
144
145
36.5k
        while (!(*s & 0x80)) {
146
21.0k
            if (++s == e) {
147
7.87k
                return true;
148
7.87k
            }
149
21.0k
        }
150
151
15.4k
        if ((s[0] & 0x60) == 0x40) {
152
2.23k
            if (s + 1 >= e || (s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) {
153
1.41k
                return false;
154
1.41k
            }
155
822
            s += 2;
156
13.2k
        } else if ((s[0] & 0xf0) == 0xe0) {
157
2.67k
            if (s + 2 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
158
1.87k
                    (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || (s[0] == 0xed && (s[1] & 0xe0) == 0xa0)) {
159
1.87k
                return false;
160
1.87k
            }
161
796
            s += 3;
162
10.5k
        } else if ((s[0] & 0xf8) == 0xf0) {
163
2.87k
            if (s + 3 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
164
2.22k
                    (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) {
165
2.22k
                return false;
166
2.22k
            }
167
653
            s += 4;
168
7.65k
        } else {
169
7.65k
            return false;
170
7.65k
        }
171
15.4k
    }
172
5.97k
    return true;
173
27.0k
}
EpollEchoServerPubSub.cpp:uWS::protocol::isValidUtf8(unsigned char*, unsigned long)
Line
Count
Source
134
1.02M
{
135
1.03M
    for (unsigned char *e = s + length; s != e; ) {
136
1.01M
        if (s + 16 <= e) {
137
5.40k
            uint64_t tmp[2];
138
5.40k
            memcpy(tmp, s, 16);
139
5.40k
            if (((tmp[0] & 0x8080808080808080) | (tmp[1] & 0x8080808080808080)) == 0) {
140
3.59k
                s += 16;
141
3.59k
                continue;
142
3.59k
            }
143
5.40k
        }
144
145
1.32M
        while (!(*s & 0x80)) {
146
1.30M
            if (++s == e) {
147
993k
                return true;
148
993k
            }
149
1.30M
        }
150
151
21.2k
        if ((s[0] & 0x60) == 0x40) {
152
2.91k
            if (s + 1 >= e || (s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) {
153
2.60k
                return false;
154
2.60k
            }
155
302
            s += 2;
156
18.3k
        } else if ((s[0] & 0xf0) == 0xe0) {
157
2.59k
            if (s + 2 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
158
1.61k
                    (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || (s[0] == 0xed && (s[1] & 0xe0) == 0xa0)) {
159
1.53k
                return false;
160
1.53k
            }
161
1.05k
            s += 3;
162
15.7k
        } else if ((s[0] & 0xf8) == 0xf0) {
163
14.6k
            if (s + 3 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
164
13.9k
                    (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) {
165
13.9k
                return false;
166
13.9k
            }
167
611
            s += 4;
168
1.13k
        } else {
169
1.13k
            return false;
170
1.13k
        }
171
21.2k
    }
172
11.9k
    return true;
173
1.02M
}
EpollHelloWorld.cpp:uWS::protocol::isValidUtf8(unsigned char*, unsigned long)
Line
Count
Source
134
14.9k
{
135
24.2k
    for (unsigned char *e = s + length; s != e; ) {
136
23.0k
        if (s + 16 <= e) {
137
8.87k
            uint64_t tmp[2];
138
8.87k
            memcpy(tmp, s, 16);
139
8.87k
            if (((tmp[0] & 0x8080808080808080) | (tmp[1] & 0x8080808080808080)) == 0) {
140
6.26k
                s += 16;
141
6.26k
                continue;
142
6.26k
            }
143
8.87k
        }
144
145
27.9k
        while (!(*s & 0x80)) {
146
20.2k
            if (++s == e) {
147
9.04k
                return true;
148
9.04k
            }
149
20.2k
        }
150
151
7.70k
        if ((s[0] & 0x60) == 0x40) {
152
2.45k
            if (s + 1 >= e || (s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) {
153
963
                return false;
154
963
            }
155
1.49k
            s += 2;
156
5.25k
        } else if ((s[0] & 0xf0) == 0xe0) {
157
2.20k
            if (s + 2 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
158
1.38k
                    (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || (s[0] == 0xed && (s[1] & 0xe0) == 0xa0)) {
159
1.37k
                return false;
160
1.37k
            }
161
829
            s += 3;
162
3.04k
        } else if ((s[0] & 0xf8) == 0xf0) {
163
2.37k
            if (s + 3 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
164
1.72k
                    (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) {
165
1.72k
                return false;
166
1.72k
            }
167
648
            s += 4;
168
672
        } else {
169
672
            return false;
170
672
        }
171
7.70k
    }
172
1.20k
    return true;
173
14.9k
}
EpollEchoServer.cpp:uWS::protocol::isValidUtf8(unsigned char*, unsigned long)
Line
Count
Source
134
80.2k
{
135
86.6k
    for (unsigned char *e = s + length; s != e; ) {
136
85.1k
        if (s + 16 <= e) {
137
6.57k
            uint64_t tmp[2];
138
6.57k
            memcpy(tmp, s, 16);
139
6.57k
            if (((tmp[0] & 0x8080808080808080) | (tmp[1] & 0x8080808080808080)) == 0) {
140
3.35k
                s += 16;
141
3.35k
                continue;
142
3.35k
            }
143
6.57k
        }
144
145
362k
        while (!(*s & 0x80)) {
146
353k
            if (++s == e) {
147
72.4k
                return true;
148
72.4k
            }
149
353k
        }
150
151
9.29k
        if ((s[0] & 0x60) == 0x40) {
152
1.68k
            if (s + 1 >= e || (s[1] & 0xc0) != 0x80 || (s[0] & 0xfe) == 0xc0) {
153
762
                return false;
154
762
            }
155
925
            s += 2;
156
7.60k
        } else if ((s[0] & 0xf0) == 0xe0) {
157
1.83k
            if (s + 2 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 ||
158
1.19k
                    (s[0] == 0xe0 && (s[1] & 0xe0) == 0x80) || (s[0] == 0xed && (s[1] & 0xe0) == 0xa0)) {
159
1.19k
                return false;
160
1.19k
            }
161
637
            s += 3;
162
5.76k
        } else if ((s[0] & 0xf8) == 0xf0) {
163
3.34k
            if (s + 3 >= e || (s[1] & 0xc0) != 0x80 || (s[2] & 0xc0) != 0x80 || (s[3] & 0xc0) != 0x80 ||
164
2.09k
                    (s[0] == 0xf0 && (s[1] & 0xf0) == 0x80) || (s[0] == 0xf4 && s[1] > 0x8f) || s[0] > 0xf4) {
165
1.86k
                return false;
166
1.86k
            }
167
1.47k
            s += 4;
168
2.42k
        } else {
169
2.42k
            return false;
170
2.42k
        }
171
9.29k
    }
172
1.51k
    return true;
173
80.2k
}
Unexecuted instantiation: AsyncEpollHelloWorld.cpp:uWS::protocol::isValidUtf8(unsigned char*, unsigned long)
174
175
#endif
176
177
struct CloseFrame {
178
    uint16_t code;
179
    char *message;
180
    size_t length;
181
};
182
183
63.3k
static inline CloseFrame parseClosePayload(char *src, size_t length) {
184
    /* If we get no code or message, default to reporting 1005 no status code present */
185
63.3k
    CloseFrame cf = {1005, nullptr, 0};
186
63.3k
    if (length >= 2) {
187
59.5k
        memcpy(&cf.code, src, 2);
188
59.5k
        cf = {cond_byte_swap<uint16_t>(cf.code), src + 2, length - 2};
189
59.5k
        if (cf.code < 1000 || cf.code > 4999 || (cf.code > 1011 && cf.code < 4000) ||
190
56.8k
            (cf.code >= 1004 && cf.code <= 1006) || !isValidUtf8((unsigned char *) cf.message, cf.length)) {
191
            /* Even though we got a WebSocket close frame, it in itself is abnormal */
192
56.8k
            return {1006, (char *) ERR_INVALID_CLOSE_PAYLOAD.data(), ERR_INVALID_CLOSE_PAYLOAD.length()};
193
56.8k
        }
194
59.5k
    }
195
6.55k
    return cf;
196
63.3k
}
WebSocket.cpp:uWS::protocol::parseClosePayload(char*, unsigned long)
Line
Count
Source
183
41.7k
static inline CloseFrame parseClosePayload(char *src, size_t length) {
184
    /* If we get no code or message, default to reporting 1005 no status code present */
185
41.7k
    CloseFrame cf = {1005, nullptr, 0};
186
41.7k
    if (length >= 2) {
187
39.8k
        memcpy(&cf.code, src, 2);
188
39.8k
        cf = {cond_byte_swap<uint16_t>(cf.code), src + 2, length - 2};
189
39.8k
        if (cf.code < 1000 || cf.code > 4999 || (cf.code > 1011 && cf.code < 4000) ||
190
39.6k
            (cf.code >= 1004 && cf.code <= 1006) || !isValidUtf8((unsigned char *) cf.message, cf.length)) {
191
            /* Even though we got a WebSocket close frame, it in itself is abnormal */
192
39.6k
            return {1006, (char *) ERR_INVALID_CLOSE_PAYLOAD.data(), ERR_INVALID_CLOSE_PAYLOAD.length()};
193
39.6k
        }
194
39.8k
    }
195
2.13k
    return cf;
196
41.7k
}
EpollEchoServerPubSub.cpp:uWS::protocol::parseClosePayload(char*, unsigned long)
Line
Count
Source
183
9.96k
static inline CloseFrame parseClosePayload(char *src, size_t length) {
184
    /* If we get no code or message, default to reporting 1005 no status code present */
185
9.96k
    CloseFrame cf = {1005, nullptr, 0};
186
9.96k
    if (length >= 2) {
187
9.00k
        memcpy(&cf.code, src, 2);
188
9.00k
        cf = {cond_byte_swap<uint16_t>(cf.code), src + 2, length - 2};
189
9.00k
        if (cf.code < 1000 || cf.code > 4999 || (cf.code > 1011 && cf.code < 4000) ||
190
8.17k
            (cf.code >= 1004 && cf.code <= 1006) || !isValidUtf8((unsigned char *) cf.message, cf.length)) {
191
            /* Even though we got a WebSocket close frame, it in itself is abnormal */
192
8.17k
            return {1006, (char *) ERR_INVALID_CLOSE_PAYLOAD.data(), ERR_INVALID_CLOSE_PAYLOAD.length()};
193
8.17k
        }
194
9.00k
    }
195
1.78k
    return cf;
196
9.96k
}
EpollHelloWorld.cpp:uWS::protocol::parseClosePayload(char*, unsigned long)
Line
Count
Source
183
6.02k
static inline CloseFrame parseClosePayload(char *src, size_t length) {
184
    /* If we get no code or message, default to reporting 1005 no status code present */
185
6.02k
    CloseFrame cf = {1005, nullptr, 0};
186
6.02k
    if (length >= 2) {
187
5.58k
        memcpy(&cf.code, src, 2);
188
5.58k
        cf = {cond_byte_swap<uint16_t>(cf.code), src + 2, length - 2};
189
5.58k
        if (cf.code < 1000 || cf.code > 4999 || (cf.code > 1011 && cf.code < 4000) ||
190
4.45k
            (cf.code >= 1004 && cf.code <= 1006) || !isValidUtf8((unsigned char *) cf.message, cf.length)) {
191
            /* Even though we got a WebSocket close frame, it in itself is abnormal */
192
4.45k
            return {1006, (char *) ERR_INVALID_CLOSE_PAYLOAD.data(), ERR_INVALID_CLOSE_PAYLOAD.length()};
193
4.45k
        }
194
5.58k
    }
195
1.56k
    return cf;
196
6.02k
}
EpollEchoServer.cpp:uWS::protocol::parseClosePayload(char*, unsigned long)
Line
Count
Source
183
5.58k
static inline CloseFrame parseClosePayload(char *src, size_t length) {
184
    /* If we get no code or message, default to reporting 1005 no status code present */
185
5.58k
    CloseFrame cf = {1005, nullptr, 0};
186
5.58k
    if (length >= 2) {
187
5.15k
        memcpy(&cf.code, src, 2);
188
5.15k
        cf = {cond_byte_swap<uint16_t>(cf.code), src + 2, length - 2};
189
5.15k
        if (cf.code < 1000 || cf.code > 4999 || (cf.code > 1011 && cf.code < 4000) ||
190
4.51k
            (cf.code >= 1004 && cf.code <= 1006) || !isValidUtf8((unsigned char *) cf.message, cf.length)) {
191
            /* Even though we got a WebSocket close frame, it in itself is abnormal */
192
4.51k
            return {1006, (char *) ERR_INVALID_CLOSE_PAYLOAD.data(), ERR_INVALID_CLOSE_PAYLOAD.length()};
193
4.51k
        }
194
5.15k
    }
195
1.07k
    return cf;
196
5.58k
}
Unexecuted instantiation: AsyncEpollHelloWorld.cpp:uWS::protocol::parseClosePayload(char*, unsigned long)
197
198
23.8k
static inline size_t formatClosePayload(char *dst, uint16_t code, const char *message, size_t length) {
199
    /* We could have more strict checks here, but never append code 0 or 1005 or 1006 */
200
23.8k
    if (code && code != 1005 && code != 1006) {
201
4.09k
        code = cond_byte_swap<uint16_t>(code);
202
4.09k
        memcpy(dst, &code, 2);
203
        /* It is invalid to pass nullptr to memcpy, even though length is 0 */
204
4.09k
        if (message) {
205
2.59k
            memcpy(dst + 2, message, length);
206
2.59k
        }
207
4.09k
        return length + 2;
208
4.09k
    }
209
19.7k
    return 0;
210
23.8k
}
Unexecuted instantiation: WebSocket.cpp:uWS::protocol::formatClosePayload(char*, unsigned short, char const*, unsigned long)
EpollEchoServerPubSub.cpp:uWS::protocol::formatClosePayload(char*, unsigned short, char const*, unsigned long)
Line
Count
Source
198
9.96k
static inline size_t formatClosePayload(char *dst, uint16_t code, const char *message, size_t length) {
199
    /* We could have more strict checks here, but never append code 0 or 1005 or 1006 */
200
9.96k
    if (code && code != 1005 && code != 1006) {
201
832
        code = cond_byte_swap<uint16_t>(code);
202
832
        memcpy(dst, &code, 2);
203
        /* It is invalid to pass nullptr to memcpy, even though length is 0 */
204
832
        if (message) {
205
832
            memcpy(dst + 2, message, length);
206
832
        }
207
832
        return length + 2;
208
832
    }
209
9.13k
    return 0;
210
9.96k
}
EpollHelloWorld.cpp:uWS::protocol::formatClosePayload(char*, unsigned short, char const*, unsigned long)
Line
Count
Source
198
6.02k
static inline size_t formatClosePayload(char *dst, uint16_t code, const char *message, size_t length) {
199
    /* We could have more strict checks here, but never append code 0 or 1005 or 1006 */
200
6.02k
    if (code && code != 1005 && code != 1006) {
201
1.12k
        code = cond_byte_swap<uint16_t>(code);
202
1.12k
        memcpy(dst, &code, 2);
203
        /* It is invalid to pass nullptr to memcpy, even though length is 0 */
204
1.12k
        if (message) {
205
1.12k
            memcpy(dst + 2, message, length);
206
1.12k
        }
207
1.12k
        return length + 2;
208
1.12k
    }
209
4.89k
    return 0;
210
6.02k
}
EpollEchoServer.cpp:uWS::protocol::formatClosePayload(char*, unsigned short, char const*, unsigned long)
Line
Count
Source
198
7.85k
static inline size_t formatClosePayload(char *dst, uint16_t code, const char *message, size_t length) {
199
    /* We could have more strict checks here, but never append code 0 or 1005 or 1006 */
200
7.85k
    if (code && code != 1005 && code != 1006) {
201
2.13k
        code = cond_byte_swap<uint16_t>(code);
202
2.13k
        memcpy(dst, &code, 2);
203
        /* It is invalid to pass nullptr to memcpy, even though length is 0 */
204
2.13k
        if (message) {
205
640
            memcpy(dst + 2, message, length);
206
640
        }
207
2.13k
        return length + 2;
208
2.13k
    }
209
5.71k
    return 0;
210
7.85k
}
Unexecuted instantiation: AsyncEpollHelloWorld.cpp:uWS::protocol::formatClosePayload(char*, unsigned short, char const*, unsigned long)
211
212
157k
static inline size_t messageFrameSize(size_t messageSize) {
213
157k
    if (messageSize < 126) {
214
152k
        return 2 + messageSize;
215
152k
    } else if (messageSize <= UINT16_MAX) {
216
5.73k
        return 4 + messageSize;
217
5.73k
    }
218
0
    return 10 + messageSize;
219
157k
}
Unexecuted instantiation: WebSocket.cpp:uWS::protocol::messageFrameSize(unsigned long)
EpollEchoServerPubSub.cpp:uWS::protocol::messageFrameSize(unsigned long)
Line
Count
Source
212
37.6k
static inline size_t messageFrameSize(size_t messageSize) {
213
37.6k
    if (messageSize < 126) {
214
37.3k
        return 2 + messageSize;
215
37.3k
    } else if (messageSize <= UINT16_MAX) {
216
229
        return 4 + messageSize;
217
229
    }
218
0
    return 10 + messageSize;
219
37.6k
}
EpollHelloWorld.cpp:uWS::protocol::messageFrameSize(unsigned long)
Line
Count
Source
212
23.8k
static inline size_t messageFrameSize(size_t messageSize) {
213
23.8k
    if (messageSize < 126) {
214
23.1k
        return 2 + messageSize;
215
23.1k
    } else if (messageSize <= UINT16_MAX) {
216
650
        return 4 + messageSize;
217
650
    }
218
0
    return 10 + messageSize;
219
23.8k
}
EpollEchoServer.cpp:uWS::protocol::messageFrameSize(unsigned long)
Line
Count
Source
212
96.3k
static inline size_t messageFrameSize(size_t messageSize) {
213
96.3k
    if (messageSize < 126) {
214
91.4k
        return 2 + messageSize;
215
91.4k
    } else if (messageSize <= UINT16_MAX) {
216
4.85k
        return 4 + messageSize;
217
4.85k
    }
218
0
    return 10 + messageSize;
219
96.3k
}
Unexecuted instantiation: AsyncEpollHelloWorld.cpp:uWS::protocol::messageFrameSize(unsigned long)
220
221
enum {
222
    SND_CONTINUATION = 1,
223
    SND_NO_FIN = 2,
224
    SND_COMPRESSED = 64
225
};
226
227
template <bool isServer>
228
157k
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed, bool fin) {
229
157k
    size_t messageLength;
230
157k
    size_t headerLength;
231
157k
    if (reportedLength < 126) {
232
152k
        headerLength = 2;
233
152k
        dst[1] = (char) reportedLength;
234
152k
    } else if (reportedLength <= UINT16_MAX) {
235
5.73k
        headerLength = 4;
236
5.73k
        dst[1] = 126;
237
5.73k
        uint16_t tmp = cond_byte_swap<uint16_t>((uint16_t) reportedLength);
238
5.73k
        memcpy(&dst[2], &tmp, sizeof(uint16_t));
239
5.73k
    } else {
240
0
        headerLength = 10;
241
0
        dst[1] = 127;
242
0
        uint64_t tmp = cond_byte_swap<uint64_t>((uint64_t) reportedLength);
243
0
        memcpy(&dst[2], &tmp, sizeof(uint64_t));
244
0
    }
245
246
157k
    dst[0] = (char) ((fin ? 128 : 0) | ((compressed && opCode) ? SND_COMPRESSED : 0) | (char) opCode);
247
248
    //printf("%d\n", (int)dst[0]);
249
250
157k
    char mask[4];
251
157k
    if (!isServer) {
252
0
        dst[1] |= 0x80;
253
0
        uint32_t random = (uint32_t) rand();
254
0
        memcpy(mask, &random, 4);
255
0
        memcpy(dst + headerLength, &random, 4);
256
0
        headerLength += 4;
257
0
    }
258
259
157k
    messageLength = headerLength + length;
260
157k
    memcpy(dst + headerLength, src, length);
261
262
157k
    if (!isServer) {
263
264
        // overwrites up to 3 bytes outside of the given buffer!
265
        //WebSocketProtocol<isServer>::unmaskInplace(dst + headerLength, dst + headerLength + length, mask);
266
267
        // this is not optimal
268
0
        char *start = dst + headerLength;
269
0
        char *stop = start + length;
270
0
        int i = 0;
271
0
        while (start != stop) {
272
0
            (*start++) ^= mask[i++ % 4];
273
0
        }
274
0
    }
275
157k
    return messageLength;
276
157k
}
EpollEchoServerPubSub.cpp:unsigned long uWS::protocol::formatMessage<true>(char*, char const*, unsigned long, uWS::OpCode, unsigned long, bool, bool)
Line
Count
Source
228
37.6k
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed, bool fin) {
229
37.6k
    size_t messageLength;
230
37.6k
    size_t headerLength;
231
37.6k
    if (reportedLength < 126) {
232
37.3k
        headerLength = 2;
233
37.3k
        dst[1] = (char) reportedLength;
234
37.3k
    } else if (reportedLength <= UINT16_MAX) {
235
229
        headerLength = 4;
236
229
        dst[1] = 126;
237
229
        uint16_t tmp = cond_byte_swap<uint16_t>((uint16_t) reportedLength);
238
229
        memcpy(&dst[2], &tmp, sizeof(uint16_t));
239
229
    } else {
240
0
        headerLength = 10;
241
0
        dst[1] = 127;
242
0
        uint64_t tmp = cond_byte_swap<uint64_t>((uint64_t) reportedLength);
243
0
        memcpy(&dst[2], &tmp, sizeof(uint64_t));
244
0
    }
245
246
37.6k
    dst[0] = (char) ((fin ? 128 : 0) | ((compressed && opCode) ? SND_COMPRESSED : 0) | (char) opCode);
247
248
    //printf("%d\n", (int)dst[0]);
249
250
37.6k
    char mask[4];
251
37.6k
    if (!isServer) {
252
0
        dst[1] |= 0x80;
253
0
        uint32_t random = (uint32_t) rand();
254
0
        memcpy(mask, &random, 4);
255
0
        memcpy(dst + headerLength, &random, 4);
256
0
        headerLength += 4;
257
0
    }
258
259
37.6k
    messageLength = headerLength + length;
260
37.6k
    memcpy(dst + headerLength, src, length);
261
262
37.6k
    if (!isServer) {
263
264
        // overwrites up to 3 bytes outside of the given buffer!
265
        //WebSocketProtocol<isServer>::unmaskInplace(dst + headerLength, dst + headerLength + length, mask);
266
267
        // this is not optimal
268
0
        char *start = dst + headerLength;
269
0
        char *stop = start + length;
270
0
        int i = 0;
271
0
        while (start != stop) {
272
0
            (*start++) ^= mask[i++ % 4];
273
0
        }
274
0
    }
275
37.6k
    return messageLength;
276
37.6k
}
EpollHelloWorld.cpp:unsigned long uWS::protocol::formatMessage<true>(char*, char const*, unsigned long, uWS::OpCode, unsigned long, bool, bool)
Line
Count
Source
228
23.8k
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed, bool fin) {
229
23.8k
    size_t messageLength;
230
23.8k
    size_t headerLength;
231
23.8k
    if (reportedLength < 126) {
232
23.1k
        headerLength = 2;
233
23.1k
        dst[1] = (char) reportedLength;
234
23.1k
    } else if (reportedLength <= UINT16_MAX) {
235
650
        headerLength = 4;
236
650
        dst[1] = 126;
237
650
        uint16_t tmp = cond_byte_swap<uint16_t>((uint16_t) reportedLength);
238
650
        memcpy(&dst[2], &tmp, sizeof(uint16_t));
239
650
    } else {
240
0
        headerLength = 10;
241
0
        dst[1] = 127;
242
0
        uint64_t tmp = cond_byte_swap<uint64_t>((uint64_t) reportedLength);
243
0
        memcpy(&dst[2], &tmp, sizeof(uint64_t));
244
0
    }
245
246
23.8k
    dst[0] = (char) ((fin ? 128 : 0) | ((compressed && opCode) ? SND_COMPRESSED : 0) | (char) opCode);
247
248
    //printf("%d\n", (int)dst[0]);
249
250
23.8k
    char mask[4];
251
23.8k
    if (!isServer) {
252
0
        dst[1] |= 0x80;
253
0
        uint32_t random = (uint32_t) rand();
254
0
        memcpy(mask, &random, 4);
255
0
        memcpy(dst + headerLength, &random, 4);
256
0
        headerLength += 4;
257
0
    }
258
259
23.8k
    messageLength = headerLength + length;
260
23.8k
    memcpy(dst + headerLength, src, length);
261
262
23.8k
    if (!isServer) {
263
264
        // overwrites up to 3 bytes outside of the given buffer!
265
        //WebSocketProtocol<isServer>::unmaskInplace(dst + headerLength, dst + headerLength + length, mask);
266
267
        // this is not optimal
268
0
        char *start = dst + headerLength;
269
0
        char *stop = start + length;
270
0
        int i = 0;
271
0
        while (start != stop) {
272
0
            (*start++) ^= mask[i++ % 4];
273
0
        }
274
0
    }
275
23.8k
    return messageLength;
276
23.8k
}
EpollEchoServer.cpp:unsigned long uWS::protocol::formatMessage<true>(char*, char const*, unsigned long, uWS::OpCode, unsigned long, bool, bool)
Line
Count
Source
228
96.3k
static inline size_t formatMessage(char *dst, const char *src, size_t length, OpCode opCode, size_t reportedLength, bool compressed, bool fin) {
229
96.3k
    size_t messageLength;
230
96.3k
    size_t headerLength;
231
96.3k
    if (reportedLength < 126) {
232
91.4k
        headerLength = 2;
233
91.4k
        dst[1] = (char) reportedLength;
234
91.4k
    } else if (reportedLength <= UINT16_MAX) {
235
4.85k
        headerLength = 4;
236
4.85k
        dst[1] = 126;
237
4.85k
        uint16_t tmp = cond_byte_swap<uint16_t>((uint16_t) reportedLength);
238
4.85k
        memcpy(&dst[2], &tmp, sizeof(uint16_t));
239
4.85k
    } else {
240
0
        headerLength = 10;
241
0
        dst[1] = 127;
242
0
        uint64_t tmp = cond_byte_swap<uint64_t>((uint64_t) reportedLength);
243
0
        memcpy(&dst[2], &tmp, sizeof(uint64_t));
244
0
    }
245
246
96.3k
    dst[0] = (char) ((fin ? 128 : 0) | ((compressed && opCode) ? SND_COMPRESSED : 0) | (char) opCode);
247
248
    //printf("%d\n", (int)dst[0]);
249
250
96.3k
    char mask[4];
251
96.3k
    if (!isServer) {
252
0
        dst[1] |= 0x80;
253
0
        uint32_t random = (uint32_t) rand();
254
0
        memcpy(mask, &random, 4);
255
0
        memcpy(dst + headerLength, &random, 4);
256
0
        headerLength += 4;
257
0
    }
258
259
96.3k
    messageLength = headerLength + length;
260
96.3k
    memcpy(dst + headerLength, src, length);
261
262
96.3k
    if (!isServer) {
263
264
        // overwrites up to 3 bytes outside of the given buffer!
265
        //WebSocketProtocol<isServer>::unmaskInplace(dst + headerLength, dst + headerLength + length, mask);
266
267
        // this is not optimal
268
0
        char *start = dst + headerLength;
269
0
        char *stop = start + length;
270
0
        int i = 0;
271
0
        while (start != stop) {
272
0
            (*start++) ^= mask[i++ % 4];
273
0
        }
274
0
    }
275
96.3k
    return messageLength;
276
96.3k
}
277
278
}
279
280
// essentially this is only a parser
281
template <const bool isServer, typename Impl>
282
struct WebSocketProtocol {
283
public:
284
    static const unsigned int SHORT_MESSAGE_HEADER = isServer ? 6 : 2;
285
    static const unsigned int MEDIUM_MESSAGE_HEADER = isServer ? 8 : 4;
286
    static const unsigned int LONG_MESSAGE_HEADER = isServer ? 14 : 10;
287
288
protected:
289
2.65M
    static inline bool isFin(char *frame) {return *((unsigned char *) frame) & 128;}
uWS::WebSocketProtocol<true, Impl>::isFin(char*)
Line
Count
Source
289
163k
    static inline bool isFin(char *frame) {return *((unsigned char *) frame) & 128;}
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::isFin(char*)
Line
Count
Source
289
2.13M
    static inline bool isFin(char *frame) {return *((unsigned char *) frame) & 128;}
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::isFin(char*)
Line
Count
Source
289
102k
    static inline bool isFin(char *frame) {return *((unsigned char *) frame) & 128;}
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::isFin(char*)
Line
Count
Source
289
255k
    static inline bool isFin(char *frame) {return *((unsigned char *) frame) & 128;}
290
6.67M
    static inline unsigned char getOpCode(char *frame) {return *((unsigned char *) frame) & 15;}
uWS::WebSocketProtocol<true, Impl>::getOpCode(char*)
Line
Count
Source
290
467k
    static inline unsigned char getOpCode(char *frame) {return *((unsigned char *) frame) & 15;}
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::getOpCode(char*)
Line
Count
Source
290
5.32M
    static inline unsigned char getOpCode(char *frame) {return *((unsigned char *) frame) & 15;}
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::getOpCode(char*)
Line
Count
Source
290
243k
    static inline unsigned char getOpCode(char *frame) {return *((unsigned char *) frame) & 15;}
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::getOpCode(char*)
Line
Count
Source
290
631k
    static inline unsigned char getOpCode(char *frame) {return *((unsigned char *) frame) & 15;}
291
2.68M
    static inline unsigned char payloadLength(char *frame) {return ((unsigned char *) frame)[1] & 127;}
uWS::WebSocketProtocol<true, Impl>::payloadLength(char*)
Line
Count
Source
291
176k
    static inline unsigned char payloadLength(char *frame) {return ((unsigned char *) frame)[1] & 127;}
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::payloadLength(char*)
Line
Count
Source
291
2.14M
    static inline unsigned char payloadLength(char *frame) {return ((unsigned char *) frame)[1] & 127;}
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::payloadLength(char*)
Line
Count
Source
291
108k
    static inline unsigned char payloadLength(char *frame) {return ((unsigned char *) frame)[1] & 127;}
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::payloadLength(char*)
Line
Count
Source
291
262k
    static inline unsigned char payloadLength(char *frame) {return ((unsigned char *) frame)[1] & 127;}
292
1.47M
    static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
uWS::WebSocketProtocol<true, Impl>::rsv23(char*)
Line
Count
Source
292
221k
    static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::rsv23(char*)
Line
Count
Source
292
1.07M
    static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rsv23(char*)
Line
Count
Source
292
47.4k
    static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rsv23(char*)
Line
Count
Source
292
127k
    static inline bool rsv23(char *frame) {return *((unsigned char *) frame) & 48;}
293
1.50M
    static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
uWS::WebSocketProtocol<true, Impl>::rsv1(char*)
Line
Count
Source
293
221k
    static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::rsv1(char*)
Line
Count
Source
293
1.09M
    static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rsv1(char*)
Line
Count
Source
293
48.2k
    static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rsv1(char*)
Line
Count
Source
293
135k
    static inline bool rsv1(char *frame) {return *((unsigned char *) frame) & 64;}
294
295
    template <int N>
296
0
    static inline void UnrolledXor(char * __restrict data, char * __restrict mask) {
297
0
        if constexpr (N != 1) {
298
0
            UnrolledXor<N - 1>(data, mask);
299
0
        }
300
0
        data[N - 1] ^= mask[(N - 1) % 4];
301
0
    }
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<16>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<15>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<14>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<13>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<12>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<11>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<10>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<9>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<8>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<7>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<6>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<5>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<4>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<3>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<2>(char*, char*)
Unexecuted instantiation: void uWS::WebSocketProtocol<true, Impl>::UnrolledXor<1>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<16>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<15>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<14>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<13>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<12>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<11>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<10>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<9>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<8>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<7>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<6>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<5>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<4>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<3>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<2>(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::UnrolledXor<1>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<16>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<15>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<14>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<13>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<12>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<11>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<10>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<9>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<8>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<7>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<6>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<5>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<4>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<3>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<2>(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<1>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<16>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<15>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<14>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<13>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<12>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<11>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<10>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<9>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<8>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<7>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<6>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<5>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<4>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<3>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<2>(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::UnrolledXor<1>(char*, char*)
302
303
    template <int DESTINATION>
304
61.4k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
451k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
390k
            uint64_t loaded;
307
390k
            memcpy(&loaded, src, 8);
308
390k
            loaded ^= mask;
309
390k
            memcpy(src - DESTINATION, &loaded, 8);
310
390k
            src += 8;
311
390k
        }
312
61.4k
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImprecise8<0>(char*, unsigned long, unsigned int)
Line
Count
Source
304
9.13k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
59.3k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
50.2k
            uint64_t loaded;
307
50.2k
            memcpy(&loaded, src, 8);
308
50.2k
            loaded ^= mask;
309
50.2k
            memcpy(src - DESTINATION, &loaded, 8);
310
50.2k
            src += 8;
311
50.2k
        }
312
9.13k
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImprecise8<8>(char*, unsigned long, unsigned int)
Line
Count
Source
304
3.33k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
37.9k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
34.6k
            uint64_t loaded;
307
34.6k
            memcpy(&loaded, src, 8);
308
34.6k
            loaded ^= mask;
309
34.6k
            memcpy(src - DESTINATION, &loaded, 8);
310
34.6k
            src += 8;
311
34.6k
        }
312
3.33k
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImprecise8<14>(char*, unsigned long, unsigned int)
Line
Count
Source
304
1.73k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
38.6k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
36.9k
            uint64_t loaded;
307
36.9k
            memcpy(&loaded, src, 8);
308
36.9k
            loaded ^= mask;
309
36.9k
            memcpy(src - DESTINATION, &loaded, 8);
310
36.9k
            src += 8;
311
36.9k
        }
312
1.73k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImprecise8<0>(char*, unsigned long, unsigned int)
Line
Count
Source
304
10.7k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
73.5k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
62.7k
            uint64_t loaded;
307
62.7k
            memcpy(&loaded, src, 8);
308
62.7k
            loaded ^= mask;
309
62.7k
            memcpy(src - DESTINATION, &loaded, 8);
310
62.7k
            src += 8;
311
62.7k
        }
312
10.7k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImprecise8<8>(char*, unsigned long, unsigned int)
Line
Count
Source
304
2.64k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
11.0k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
8.36k
            uint64_t loaded;
307
8.36k
            memcpy(&loaded, src, 8);
308
8.36k
            loaded ^= mask;
309
8.36k
            memcpy(src - DESTINATION, &loaded, 8);
310
8.36k
            src += 8;
311
8.36k
        }
312
2.64k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImprecise8<14>(char*, unsigned long, unsigned int)
Line
Count
Source
304
1.90k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
7.89k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
5.99k
            uint64_t loaded;
307
5.99k
            memcpy(&loaded, src, 8);
308
5.99k
            loaded ^= mask;
309
5.99k
            memcpy(src - DESTINATION, &loaded, 8);
310
5.99k
            src += 8;
311
5.99k
        }
312
1.90k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<0>(char*, unsigned long, unsigned int)
Line
Count
Source
304
8.43k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
52.7k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
44.2k
            uint64_t loaded;
307
44.2k
            memcpy(&loaded, src, 8);
308
44.2k
            loaded ^= mask;
309
44.2k
            memcpy(src - DESTINATION, &loaded, 8);
310
44.2k
            src += 8;
311
44.2k
        }
312
8.43k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<8>(char*, unsigned long, unsigned int)
Line
Count
Source
304
2.23k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
12.1k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
9.86k
            uint64_t loaded;
307
9.86k
            memcpy(&loaded, src, 8);
308
9.86k
            loaded ^= mask;
309
9.86k
            memcpy(src - DESTINATION, &loaded, 8);
310
9.86k
            src += 8;
311
9.86k
        }
312
2.23k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<14>(char*, unsigned long, unsigned int)
Line
Count
Source
304
1.97k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
8.29k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
6.32k
            uint64_t loaded;
307
6.32k
            memcpy(&loaded, src, 8);
308
6.32k
            loaded ^= mask;
309
6.32k
            memcpy(src - DESTINATION, &loaded, 8);
310
6.32k
            src += 8;
311
6.32k
        }
312
1.97k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<0>(char*, unsigned long, unsigned int)
Line
Count
Source
304
9.25k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
45.0k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
35.8k
            uint64_t loaded;
307
35.8k
            memcpy(&loaded, src, 8);
308
35.8k
            loaded ^= mask;
309
35.8k
            memcpy(src - DESTINATION, &loaded, 8);
310
35.8k
            src += 8;
311
35.8k
        }
312
9.25k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<8>(char*, unsigned long, unsigned int)
Line
Count
Source
304
7.77k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
96.0k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
88.2k
            uint64_t loaded;
307
88.2k
            memcpy(&loaded, src, 8);
308
88.2k
            loaded ^= mask;
309
88.2k
            memcpy(src - DESTINATION, &loaded, 8);
310
88.2k
            src += 8;
311
88.2k
        }
312
7.77k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise8<14>(char*, unsigned long, unsigned int)
Line
Count
Source
304
2.21k
    static inline void unmaskImprecise8(char *src, uint64_t mask, unsigned int length) {
305
8.84k
        for (unsigned int n = (length >> 3) + 1; n; n--) {
306
6.62k
            uint64_t loaded;
307
6.62k
            memcpy(&loaded, src, 8);
308
6.62k
            loaded ^= mask;
309
6.62k
            memcpy(src - DESTINATION, &loaded, 8);
310
6.62k
            src += 8;
311
6.62k
        }
312
2.21k
    }
313
314
    /* DESTINATION = 6 makes this not SIMD, DESTINATION = 4 is with SIMD but we don't want that for short messages */
315
    template <int DESTINATION>
316
1.21M
    static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) {
317
2.86M
        for (unsigned int n = (length >> 2) + 1; n; n--) {
318
1.64M
            uint32_t loaded;
319
1.64M
            memcpy(&loaded, src, 4);
320
1.64M
            loaded ^= mask;
321
1.64M
            memcpy(src - DESTINATION, &loaded, 4);
322
1.64M
            src += 4;
323
1.64M
        }
324
1.21M
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImprecise4<6>(char*, unsigned int, unsigned int)
Line
Count
Source
316
47.4k
    static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) {
317
236k
        for (unsigned int n = (length >> 2) + 1; n; n--) {
318
189k
            uint32_t loaded;
319
189k
            memcpy(&loaded, src, 4);
320
189k
            loaded ^= mask;
321
189k
            memcpy(src - DESTINATION, &loaded, 4);
322
189k
            src += 4;
323
189k
        }
324
47.4k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImprecise4<6>(char*, unsigned int, unsigned int)
Line
Count
Source
316
1.04M
    static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) {
317
2.20M
        for (unsigned int n = (length >> 2) + 1; n; n--) {
318
1.16M
            uint32_t loaded;
319
1.16M
            memcpy(&loaded, src, 4);
320
1.16M
            loaded ^= mask;
321
1.16M
            memcpy(src - DESTINATION, &loaded, 4);
322
1.16M
            src += 4;
323
1.16M
        }
324
1.04M
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise4<6>(char*, unsigned int, unsigned int)
Line
Count
Source
316
30.0k
    static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) {
317
109k
        for (unsigned int n = (length >> 2) + 1; n; n--) {
318
79.7k
            uint32_t loaded;
319
79.7k
            memcpy(&loaded, src, 4);
320
79.7k
            loaded ^= mask;
321
79.7k
            memcpy(src - DESTINATION, &loaded, 4);
322
79.7k
            src += 4;
323
79.7k
        }
324
30.0k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImprecise4<6>(char*, unsigned int, unsigned int)
Line
Count
Source
316
98.8k
    static inline void unmaskImprecise4(char *src, uint32_t mask, unsigned int length) {
317
310k
        for (unsigned int n = (length >> 2) + 1; n; n--) {
318
211k
            uint32_t loaded;
319
211k
            memcpy(&loaded, src, 4);
320
211k
            loaded ^= mask;
321
211k
            memcpy(src - DESTINATION, &loaded, 4);
322
211k
            src += 4;
323
211k
        }
324
98.8k
    }
325
326
    template <int HEADER_SIZE>
327
1.24M
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
1.24M
        if constexpr (HEADER_SIZE != 6) {
329
23.8k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
23.8k
            uint64_t maskInt;
331
23.8k
            memcpy(&maskInt, mask, 8);
332
23.8k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
1.21M
        } else {
334
1.21M
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
1.21M
            uint32_t maskInt;
336
1.21M
            memcpy(&maskInt, mask, 4);
337
1.21M
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
1.21M
        }
339
1.24M
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImpreciseCopyMask<6>(char*, unsigned int)
Line
Count
Source
327
47.4k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
        if constexpr (HEADER_SIZE != 6) {
329
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
            uint64_t maskInt;
331
            memcpy(&maskInt, mask, 8);
332
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
47.4k
        } else {
334
47.4k
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
47.4k
            uint32_t maskInt;
336
47.4k
            memcpy(&maskInt, mask, 4);
337
47.4k
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
47.4k
        }
339
47.4k
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImpreciseCopyMask<8>(char*, unsigned int)
Line
Count
Source
327
3.33k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
3.33k
        if constexpr (HEADER_SIZE != 6) {
329
3.33k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
3.33k
            uint64_t maskInt;
331
3.33k
            memcpy(&maskInt, mask, 8);
332
3.33k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
3.33k
    }
void uWS::WebSocketProtocol<true, Impl>::unmaskImpreciseCopyMask<14>(char*, unsigned int)
Line
Count
Source
327
1.73k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
1.73k
        if constexpr (HEADER_SIZE != 6) {
329
1.73k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
1.73k
            uint64_t maskInt;
331
1.73k
            memcpy(&maskInt, mask, 8);
332
1.73k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
1.73k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<6>(char*, unsigned int)
Line
Count
Source
327
1.04M
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
        if constexpr (HEADER_SIZE != 6) {
329
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
            uint64_t maskInt;
331
            memcpy(&maskInt, mask, 8);
332
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
1.04M
        } else {
334
1.04M
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
1.04M
            uint32_t maskInt;
336
1.04M
            memcpy(&maskInt, mask, 4);
337
1.04M
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
1.04M
        }
339
1.04M
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<8>(char*, unsigned int)
Line
Count
Source
327
2.64k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
2.64k
        if constexpr (HEADER_SIZE != 6) {
329
2.64k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
2.64k
            uint64_t maskInt;
331
2.64k
            memcpy(&maskInt, mask, 8);
332
2.64k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
2.64k
    }
EpollEchoServerPubSub.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<14>(char*, unsigned int)
Line
Count
Source
327
1.90k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
1.90k
        if constexpr (HEADER_SIZE != 6) {
329
1.90k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
1.90k
            uint64_t maskInt;
331
1.90k
            memcpy(&maskInt, mask, 8);
332
1.90k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
1.90k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<6>(char*, unsigned int)
Line
Count
Source
327
30.0k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
        if constexpr (HEADER_SIZE != 6) {
329
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
            uint64_t maskInt;
331
            memcpy(&maskInt, mask, 8);
332
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
30.0k
        } else {
334
30.0k
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
30.0k
            uint32_t maskInt;
336
30.0k
            memcpy(&maskInt, mask, 4);
337
30.0k
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
30.0k
        }
339
30.0k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<8>(char*, unsigned int)
Line
Count
Source
327
2.23k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
2.23k
        if constexpr (HEADER_SIZE != 6) {
329
2.23k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
2.23k
            uint64_t maskInt;
331
2.23k
            memcpy(&maskInt, mask, 8);
332
2.23k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
2.23k
    }
EpollHelloWorld.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<14>(char*, unsigned int)
Line
Count
Source
327
1.97k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
1.97k
        if constexpr (HEADER_SIZE != 6) {
329
1.97k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
1.97k
            uint64_t maskInt;
331
1.97k
            memcpy(&maskInt, mask, 8);
332
1.97k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
1.97k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<6>(char*, unsigned int)
Line
Count
Source
327
98.8k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
        if constexpr (HEADER_SIZE != 6) {
329
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
            uint64_t maskInt;
331
            memcpy(&maskInt, mask, 8);
332
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
98.8k
        } else {
334
98.8k
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
98.8k
            uint32_t maskInt;
336
98.8k
            memcpy(&maskInt, mask, 4);
337
98.8k
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
98.8k
        }
339
98.8k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<8>(char*, unsigned int)
Line
Count
Source
327
7.77k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
7.77k
        if constexpr (HEADER_SIZE != 6) {
329
7.77k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
7.77k
            uint64_t maskInt;
331
7.77k
            memcpy(&maskInt, mask, 8);
332
7.77k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
7.77k
    }
EpollEchoServer.cpp:void uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskImpreciseCopyMask<14>(char*, unsigned int)
Line
Count
Source
327
2.21k
    static inline void unmaskImpreciseCopyMask(char *src, unsigned int length) {
328
2.21k
        if constexpr (HEADER_SIZE != 6) {
329
2.21k
            char mask[8] = {src[-4], src[-3], src[-2], src[-1], src[-4], src[-3], src[-2], src[-1]};
330
2.21k
            uint64_t maskInt;
331
2.21k
            memcpy(&maskInt, mask, 8);
332
2.21k
            unmaskImprecise8<HEADER_SIZE>(src, maskInt, length);
333
        } else {
334
            char mask[4] = {src[-4], src[-3], src[-2], src[-1]};
335
            uint32_t maskInt;
336
            memcpy(&maskInt, mask, 4);
337
            unmaskImprecise4<HEADER_SIZE>(src, maskInt, length);
338
        }
339
2.21k
    }
340
341
80.0k
    static inline void rotateMask(unsigned int offset, char *mask) {
342
80.0k
        char originalMask[4] = {mask[0], mask[1], mask[2], mask[3]};
343
80.0k
        mask[(0 + offset) % 4] = originalMask[0];
344
80.0k
        mask[(1 + offset) % 4] = originalMask[1];
345
80.0k
        mask[(2 + offset) % 4] = originalMask[2];
346
80.0k
        mask[(3 + offset) % 4] = originalMask[3];
347
80.0k
    }
uWS::WebSocketProtocol<true, Impl>::rotateMask(unsigned int, char*)
Line
Count
Source
341
12.1k
    static inline void rotateMask(unsigned int offset, char *mask) {
342
12.1k
        char originalMask[4] = {mask[0], mask[1], mask[2], mask[3]};
343
12.1k
        mask[(0 + offset) % 4] = originalMask[0];
344
12.1k
        mask[(1 + offset) % 4] = originalMask[1];
345
12.1k
        mask[(2 + offset) % 4] = originalMask[2];
346
12.1k
        mask[(3 + offset) % 4] = originalMask[3];
347
12.1k
    }
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::rotateMask(unsigned int, char*)
Line
Count
Source
341
12.6k
    static inline void rotateMask(unsigned int offset, char *mask) {
342
12.6k
        char originalMask[4] = {mask[0], mask[1], mask[2], mask[3]};
343
12.6k
        mask[(0 + offset) % 4] = originalMask[0];
344
12.6k
        mask[(1 + offset) % 4] = originalMask[1];
345
12.6k
        mask[(2 + offset) % 4] = originalMask[2];
346
12.6k
        mask[(3 + offset) % 4] = originalMask[3];
347
12.6k
    }
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rotateMask(unsigned int, char*)
Line
Count
Source
341
44.9k
    static inline void rotateMask(unsigned int offset, char *mask) {
342
44.9k
        char originalMask[4] = {mask[0], mask[1], mask[2], mask[3]};
343
44.9k
        mask[(0 + offset) % 4] = originalMask[0];
344
44.9k
        mask[(1 + offset) % 4] = originalMask[1];
345
44.9k
        mask[(2 + offset) % 4] = originalMask[2];
346
44.9k
        mask[(3 + offset) % 4] = originalMask[3];
347
44.9k
    }
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::rotateMask(unsigned int, char*)
Line
Count
Source
341
10.3k
    static inline void rotateMask(unsigned int offset, char *mask) {
342
10.3k
        char originalMask[4] = {mask[0], mask[1], mask[2], mask[3]};
343
10.3k
        mask[(0 + offset) % 4] = originalMask[0];
344
10.3k
        mask[(1 + offset) % 4] = originalMask[1];
345
10.3k
        mask[(2 + offset) % 4] = originalMask[2];
346
10.3k
        mask[(3 + offset) % 4] = originalMask[3];
347
10.3k
    }
348
349
75.1k
    static inline void unmaskInplace(char *data, char *stop, char *mask) {
350
1.58M
        while (data < stop) {
351
1.50M
            *(data++) ^= mask[0];
352
1.50M
            *(data++) ^= mask[1];
353
1.50M
            *(data++) ^= mask[2];
354
1.50M
            *(data++) ^= mask[3];
355
1.50M
        }
356
75.1k
    }
uWS::WebSocketProtocol<true, Impl>::unmaskInplace(char*, char*, char*)
Line
Count
Source
349
15.6k
    static inline void unmaskInplace(char *data, char *stop, char *mask) {
350
144k
        while (data < stop) {
351
129k
            *(data++) ^= mask[0];
352
129k
            *(data++) ^= mask[1];
353
129k
            *(data++) ^= mask[2];
354
129k
            *(data++) ^= mask[3];
355
129k
        }
356
15.6k
    }
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskInplace(char*, char*, char*)
Line
Count
Source
349
8.61k
    static inline void unmaskInplace(char *data, char *stop, char *mask) {
350
49.6k
        while (data < stop) {
351
41.0k
            *(data++) ^= mask[0];
352
41.0k
            *(data++) ^= mask[1];
353
41.0k
            *(data++) ^= mask[2];
354
41.0k
            *(data++) ^= mask[3];
355
41.0k
        }
356
8.61k
    }
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskInplace(char*, char*, char*)
Line
Count
Source
349
42.8k
    static inline void unmaskInplace(char *data, char *stop, char *mask) {
350
1.33M
        while (data < stop) {
351
1.29M
            *(data++) ^= mask[0];
352
1.29M
            *(data++) ^= mask[1];
353
1.29M
            *(data++) ^= mask[2];
354
1.29M
            *(data++) ^= mask[3];
355
1.29M
        }
356
42.8k
    }
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskInplace(char*, char*, char*)
Line
Count
Source
349
7.98k
    static inline void unmaskInplace(char *data, char *stop, char *mask) {
350
49.5k
        while (data < stop) {
351
41.5k
            *(data++) ^= mask[0];
352
41.5k
            *(data++) ^= mask[1];
353
41.5k
            *(data++) ^= mask[2];
354
41.5k
            *(data++) ^= mask[3];
355
41.5k
        }
356
7.98k
    }
357
358
    template <unsigned int MESSAGE_HEADER, typename T>
359
1.29M
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
1.29M
        if (getOpCode(src)) {
361
1.26M
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
8.17k
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
8.17k
                return true;
364
8.17k
            }
365
1.25M
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
1.25M
        } else if (wState->state.opStack == -1) {
367
5.09k
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
5.09k
            return true;
369
5.09k
        }
370
1.28M
        wState->state.lastFin = isFin(src);
371
372
1.28M
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
2.47k
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
2.47k
            return true;
375
2.47k
        }
376
377
1.28M
        if (payLength + MESSAGE_HEADER <= length) {
378
1.24M
            bool fin = isFin(src);
379
1.24M
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
1.24M
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
1.24M
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
42.9k
                    return true;
384
42.9k
                }
385
1.24M
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.20M
            if (fin) {
392
1.16M
                wState->state.opStack--;
393
1.16M
            }
394
395
1.20M
            src += payLength + MESSAGE_HEADER;
396
1.20M
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.20M
            wState->state.spillLength = 0;
398
1.20M
            return false;
399
1.24M
        } else {
400
37.5k
            wState->state.spillLength = 0;
401
37.5k
            wState->state.wantsHead = false;
402
37.5k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
37.5k
            bool fin = isFin(src);
404
37.5k
            if constexpr (isServer) {
405
37.5k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
37.5k
                uint64_t mask;
407
37.5k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
37.5k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
37.5k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
37.5k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
37.5k
            }
412
37.5k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
37.5k
            return true;
414
37.5k
        }
415
1.28M
    }
bool uWS::WebSocketProtocol<true, Impl>::consumeMessage<6u, unsigned char>(unsigned char, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
59.2k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
59.2k
        if (getOpCode(src)) {
361
48.1k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
2.95k
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
2.95k
                return true;
364
2.95k
            }
365
45.1k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
45.1k
        } else if (wState->state.opStack == -1) {
367
1.91k
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
1.91k
            return true;
369
1.91k
        }
370
54.4k
        wState->state.lastFin = isFin(src);
371
372
54.4k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
0
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
0
            return true;
375
0
        }
376
377
54.4k
        if (payLength + MESSAGE_HEADER <= length) {
378
47.4k
            bool fin = isFin(src);
379
47.4k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
47.4k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
47.4k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
3.46k
                    return true;
384
3.46k
                }
385
47.4k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
43.9k
            if (fin) {
392
38.5k
                wState->state.opStack--;
393
38.5k
            }
394
395
43.9k
            src += payLength + MESSAGE_HEADER;
396
43.9k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
43.9k
            wState->state.spillLength = 0;
398
43.9k
            return false;
399
47.4k
        } else {
400
7.00k
            wState->state.spillLength = 0;
401
7.00k
            wState->state.wantsHead = false;
402
7.00k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
7.00k
            bool fin = isFin(src);
404
7.00k
            if constexpr (isServer) {
405
7.00k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
7.00k
                uint64_t mask;
407
7.00k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
7.00k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
7.00k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
7.00k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
7.00k
            }
412
7.00k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
7.00k
            return true;
414
7.00k
        }
415
54.4k
    }
bool uWS::WebSocketProtocol<true, Impl>::consumeMessage<8u, unsigned short>(unsigned short, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
5.15k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
5.15k
        if (getOpCode(src)) {
361
1.91k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
591
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
591
                return true;
364
591
            }
365
1.31k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
3.24k
        } else if (wState->state.opStack == -1) {
367
194
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
194
            return true;
369
194
        }
370
4.37k
        wState->state.lastFin = isFin(src);
371
372
4.37k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
243
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
243
            return true;
375
243
        }
376
377
4.12k
        if (payLength + MESSAGE_HEADER <= length) {
378
3.33k
            bool fin = isFin(src);
379
3.33k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
3.33k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
3.33k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
964
                    return true;
384
964
                }
385
3.33k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
2.37k
            if (fin) {
392
1.01k
                wState->state.opStack--;
393
1.01k
            }
394
395
2.37k
            src += payLength + MESSAGE_HEADER;
396
2.37k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
2.37k
            wState->state.spillLength = 0;
398
2.37k
            return false;
399
3.33k
        } else {
400
790
            wState->state.spillLength = 0;
401
790
            wState->state.wantsHead = false;
402
790
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
790
            bool fin = isFin(src);
404
790
            if constexpr (isServer) {
405
790
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
790
                uint64_t mask;
407
790
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
790
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
790
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
790
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
790
            }
412
790
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
790
            return true;
414
790
        }
415
4.12k
    }
bool uWS::WebSocketProtocol<true, Impl>::consumeMessage<14u, unsigned long>(unsigned long, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
4.01k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
4.01k
        if (getOpCode(src)) {
361
2.30k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
411
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
411
                return true;
364
411
            }
365
1.89k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
1.89k
        } else if (wState->state.opStack == -1) {
367
194
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
194
            return true;
369
194
        }
370
3.41k
        wState->state.lastFin = isFin(src);
371
372
3.41k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
344
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
344
            return true;
375
344
        }
376
377
3.07k
        if (payLength + MESSAGE_HEADER <= length) {
378
1.73k
            bool fin = isFin(src);
379
1.73k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
1.73k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
1.73k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
723
                    return true;
384
723
                }
385
1.73k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.01k
            if (fin) {
392
593
                wState->state.opStack--;
393
593
            }
394
395
1.01k
            src += payLength + MESSAGE_HEADER;
396
1.01k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.01k
            wState->state.spillLength = 0;
398
1.01k
            return false;
399
1.73k
        } else {
400
1.33k
            wState->state.spillLength = 0;
401
1.33k
            wState->state.wantsHead = false;
402
1.33k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.33k
            bool fin = isFin(src);
404
1.33k
            if constexpr (isServer) {
405
1.33k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.33k
                uint64_t mask;
407
1.33k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.33k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.33k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.33k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.33k
            }
412
1.33k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.33k
            return true;
414
1.33k
        }
415
3.07k
    }
EpollEchoServerPubSub.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::consumeMessage<6u, unsigned char>(unsigned char, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
1.05M
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
1.05M
        if (getOpCode(src)) {
361
1.04M
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
785
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
785
                return true;
364
785
            }
365
1.04M
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
1.04M
        } else if (wState->state.opStack == -1) {
367
345
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
345
            return true;
369
345
        }
370
1.05M
        wState->state.lastFin = isFin(src);
371
372
1.05M
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
0
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
0
            return true;
375
0
        }
376
377
1.05M
        if (payLength + MESSAGE_HEADER <= length) {
378
1.04M
            bool fin = isFin(src);
379
1.04M
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
1.04M
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
1.04M
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
21.2k
                    return true;
384
21.2k
                }
385
1.04M
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.02M
            if (fin) {
392
1.01M
                wState->state.opStack--;
393
1.01M
            }
394
395
1.02M
            src += payLength + MESSAGE_HEADER;
396
1.02M
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.02M
            wState->state.spillLength = 0;
398
1.02M
            return false;
399
1.04M
        } else {
400
8.29k
            wState->state.spillLength = 0;
401
8.29k
            wState->state.wantsHead = false;
402
8.29k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
8.29k
            bool fin = isFin(src);
404
8.29k
            if constexpr (isServer) {
405
8.29k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
8.29k
                uint64_t mask;
407
8.29k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
8.29k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
8.29k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
8.29k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
8.29k
            }
412
8.29k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
8.29k
            return true;
414
8.29k
        }
415
1.05M
    }
EpollEchoServerPubSub.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::consumeMessage<8u, unsigned short>(unsigned short, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
4.92k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
4.92k
        if (getOpCode(src)) {
361
3.69k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
396
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
396
                return true;
364
396
            }
365
3.29k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
3.29k
        } else if (wState->state.opStack == -1) {
367
204
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
204
            return true;
369
204
        }
370
4.32k
        wState->state.lastFin = isFin(src);
371
372
4.32k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
230
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
230
            return true;
375
230
        }
376
377
4.09k
        if (payLength + MESSAGE_HEADER <= length) {
378
2.64k
            bool fin = isFin(src);
379
2.64k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
2.64k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
2.64k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
231
                    return true;
384
231
                }
385
2.64k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
2.41k
            if (fin) {
392
1.81k
                wState->state.opStack--;
393
1.81k
            }
394
395
2.41k
            src += payLength + MESSAGE_HEADER;
396
2.41k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
2.41k
            wState->state.spillLength = 0;
398
2.41k
            return false;
399
2.64k
        } else {
400
1.44k
            wState->state.spillLength = 0;
401
1.44k
            wState->state.wantsHead = false;
402
1.44k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.44k
            bool fin = isFin(src);
404
1.44k
            if constexpr (isServer) {
405
1.44k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.44k
                uint64_t mask;
407
1.44k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.44k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.44k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.44k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.44k
            }
412
1.44k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.44k
            return true;
414
1.44k
        }
415
4.09k
    }
EpollEchoServerPubSub.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::consumeMessage<14u, unsigned long>(unsigned long, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
4.09k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
4.09k
        if (getOpCode(src)) {
361
2.96k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
393
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
393
                return true;
364
393
            }
365
2.57k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
2.57k
        } else if (wState->state.opStack == -1) {
367
194
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
194
            return true;
369
194
        }
370
3.51k
        wState->state.lastFin = isFin(src);
371
372
3.51k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
577
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
577
            return true;
375
577
        }
376
377
2.93k
        if (payLength + MESSAGE_HEADER <= length) {
378
1.90k
            bool fin = isFin(src);
379
1.90k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
1.90k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
1.90k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
226
                    return true;
384
226
                }
385
1.90k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.67k
            if (fin) {
392
725
                wState->state.opStack--;
393
725
            }
394
395
1.67k
            src += payLength + MESSAGE_HEADER;
396
1.67k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.67k
            wState->state.spillLength = 0;
398
1.67k
            return false;
399
1.90k
        } else {
400
1.03k
            wState->state.spillLength = 0;
401
1.03k
            wState->state.wantsHead = false;
402
1.03k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.03k
            bool fin = isFin(src);
404
1.03k
            if constexpr (isServer) {
405
1.03k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.03k
                uint64_t mask;
407
1.03k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.03k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.03k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.03k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.03k
            }
412
1.03k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.03k
            return true;
414
1.03k
        }
415
2.93k
    }
EpollHelloWorld.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<6u, unsigned char>(unsigned char, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
36.8k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
36.8k
        if (getOpCode(src)) {
361
32.5k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
481
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
481
                return true;
364
481
            }
365
32.0k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
32.0k
        } else if (wState->state.opStack == -1) {
367
216
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
216
            return true;
369
216
        }
370
36.1k
        wState->state.lastFin = isFin(src);
371
372
36.1k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
0
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
0
            return true;
375
0
        }
376
377
36.1k
        if (payLength + MESSAGE_HEADER <= length) {
378
30.0k
            bool fin = isFin(src);
379
30.0k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
30.0k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
30.0k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
6.28k
                    return true;
384
6.28k
                }
385
30.0k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
23.7k
            if (fin) {
392
17.6k
                wState->state.opStack--;
393
17.6k
            }
394
395
23.7k
            src += payLength + MESSAGE_HEADER;
396
23.7k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
23.7k
            wState->state.spillLength = 0;
398
23.7k
            return false;
399
30.0k
        } else {
400
6.15k
            wState->state.spillLength = 0;
401
6.15k
            wState->state.wantsHead = false;
402
6.15k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
6.15k
            bool fin = isFin(src);
404
6.15k
            if constexpr (isServer) {
405
6.15k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
6.15k
                uint64_t mask;
407
6.15k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
6.15k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
6.15k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
6.15k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
6.15k
            }
412
6.15k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
6.15k
            return true;
414
6.15k
        }
415
36.1k
    }
EpollHelloWorld.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<8u, unsigned short>(unsigned short, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
4.56k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
4.56k
        if (getOpCode(src)) {
361
3.76k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
520
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
520
                return true;
364
520
            }
365
3.24k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
3.24k
        } else if (wState->state.opStack == -1) {
367
196
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
196
            return true;
369
196
        }
370
3.85k
        wState->state.lastFin = isFin(src);
371
372
3.85k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
206
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
206
            return true;
375
206
        }
376
377
3.64k
        if (payLength + MESSAGE_HEADER <= length) {
378
2.23k
            bool fin = isFin(src);
379
2.23k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
2.23k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
2.23k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
246
                    return true;
384
246
                }
385
2.23k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.99k
            if (fin) {
392
1.33k
                wState->state.opStack--;
393
1.33k
            }
394
395
1.99k
            src += payLength + MESSAGE_HEADER;
396
1.99k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.99k
            wState->state.spillLength = 0;
398
1.99k
            return false;
399
2.23k
        } else {
400
1.40k
            wState->state.spillLength = 0;
401
1.40k
            wState->state.wantsHead = false;
402
1.40k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.40k
            bool fin = isFin(src);
404
1.40k
            if constexpr (isServer) {
405
1.40k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.40k
                uint64_t mask;
407
1.40k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.40k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.40k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.40k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.40k
            }
412
1.40k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.40k
            return true;
414
1.40k
        }
415
3.64k
    }
EpollHelloWorld.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<14u, unsigned long>(unsigned long, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
3.71k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
3.71k
        if (getOpCode(src)) {
361
2.80k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
389
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
389
                return true;
364
389
            }
365
2.41k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
2.41k
        } else if (wState->state.opStack == -1) {
367
194
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
194
            return true;
369
194
        }
370
3.13k
        wState->state.lastFin = isFin(src);
371
372
3.13k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
285
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
285
            return true;
375
285
        }
376
377
2.84k
        if (payLength + MESSAGE_HEADER <= length) {
378
1.97k
            bool fin = isFin(src);
379
1.97k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
1.97k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
1.97k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
750
                    return true;
384
750
                }
385
1.97k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.22k
            if (fin) {
392
581
                wState->state.opStack--;
393
581
            }
394
395
1.22k
            src += payLength + MESSAGE_HEADER;
396
1.22k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.22k
            wState->state.spillLength = 0;
398
1.22k
            return false;
399
1.97k
        } else {
400
870
            wState->state.spillLength = 0;
401
870
            wState->state.wantsHead = false;
402
870
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
870
            bool fin = isFin(src);
404
870
            if constexpr (isServer) {
405
870
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
870
                uint64_t mask;
407
870
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
870
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
870
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
870
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
870
            }
412
870
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
870
            return true;
414
870
        }
415
2.84k
    }
EpollEchoServer.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<6u, unsigned char>(unsigned char, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
106k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
106k
        if (getOpCode(src)) {
361
102k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
479
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
479
                return true;
364
479
            }
365
102k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
102k
        } else if (wState->state.opStack == -1) {
367
967
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
967
            return true;
369
967
        }
370
105k
        wState->state.lastFin = isFin(src);
371
372
105k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
0
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
0
            return true;
375
0
        }
376
377
105k
        if (payLength + MESSAGE_HEADER <= length) {
378
98.8k
            bool fin = isFin(src);
379
98.8k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
98.8k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
98.8k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
7.80k
                    return true;
384
7.80k
                }
385
98.8k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
91.0k
            if (fin) {
392
85.4k
                wState->state.opStack--;
393
85.4k
            }
394
395
91.0k
            src += payLength + MESSAGE_HEADER;
396
91.0k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
91.0k
            wState->state.spillLength = 0;
398
91.0k
            return false;
399
98.8k
        } else {
400
6.69k
            wState->state.spillLength = 0;
401
6.69k
            wState->state.wantsHead = false;
402
6.69k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
6.69k
            bool fin = isFin(src);
404
6.69k
            if constexpr (isServer) {
405
6.69k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
6.69k
                uint64_t mask;
407
6.69k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
6.69k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
6.69k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
6.69k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
6.69k
            }
412
6.69k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
6.69k
            return true;
414
6.69k
        }
415
105k
    }
EpollEchoServer.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<8u, unsigned short>(unsigned short, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
9.95k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
9.95k
        if (getOpCode(src)) {
361
8.87k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
388
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
388
                return true;
364
388
            }
365
8.48k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
8.48k
        } else if (wState->state.opStack == -1) {
367
194
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
194
            return true;
369
194
        }
370
9.36k
        wState->state.lastFin = isFin(src);
371
372
9.36k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
220
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
220
            return true;
375
220
        }
376
377
9.14k
        if (payLength + MESSAGE_HEADER <= length) {
378
7.77k
            bool fin = isFin(src);
379
7.77k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
7.77k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
7.77k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
760
                    return true;
384
760
                }
385
7.77k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
7.01k
            if (fin) {
392
6.03k
                wState->state.opStack--;
393
6.03k
            }
394
395
7.01k
            src += payLength + MESSAGE_HEADER;
396
7.01k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
7.01k
            wState->state.spillLength = 0;
398
7.01k
            return false;
399
7.77k
        } else {
400
1.37k
            wState->state.spillLength = 0;
401
1.37k
            wState->state.wantsHead = false;
402
1.37k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.37k
            bool fin = isFin(src);
404
1.37k
            if constexpr (isServer) {
405
1.37k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.37k
                uint64_t mask;
407
1.37k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.37k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.37k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.37k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.37k
            }
412
1.37k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.37k
            return true;
414
1.37k
        }
415
9.14k
    }
EpollEchoServer.cpp:bool uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeMessage<14u, unsigned long>(unsigned long, char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
359
4.45k
    static inline bool consumeMessage(T payLength, char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
360
4.45k
        if (getOpCode(src)) {
361
3.24k
            if (wState->state.opStack == 1 || (!wState->state.lastFin && getOpCode(src) < 2)) {
362
388
                Impl::forceClose(wState, user, ERR_PROTOCOL);
363
388
                return true;
364
388
            }
365
2.85k
            wState->state.opCode[++wState->state.opStack] = (OpCode) getOpCode(src);
366
2.85k
        } else if (wState->state.opStack == -1) {
367
285
            Impl::forceClose(wState, user, ERR_PROTOCOL);
368
285
            return true;
369
285
        }
370
3.77k
        wState->state.lastFin = isFin(src);
371
372
3.77k
        if (Impl::refusePayloadLength(payLength, wState, user)) {
373
369
            Impl::forceClose(wState, user, ERR_TOO_BIG_MESSAGE);
374
369
            return true;
375
369
        }
376
377
3.40k
        if (payLength + MESSAGE_HEADER <= length) {
378
2.21k
            bool fin = isFin(src);
379
2.21k
            if (isServer) {
380
                /* This guy can never be assumed to be perfectly aligned since we can get multiple messages in one read */
381
2.21k
                unmaskImpreciseCopyMask<MESSAGE_HEADER>(src + MESSAGE_HEADER, (unsigned int) payLength);
382
2.21k
                if (Impl::handleFragment(src, payLength, 0, wState->state.opCode[wState->state.opStack], fin, wState, user)) {
383
255
                    return true;
384
255
                }
385
2.21k
            } else {
386
0
                if (Impl::handleFragment(src + MESSAGE_HEADER, payLength, 0, wState->state.opCode[wState->state.opStack], isFin(src), wState, user)) {
387
0
                    return true;
388
0
                }
389
0
            }
390
391
1.96k
            if (fin) {
392
1.39k
                wState->state.opStack--;
393
1.39k
            }
394
395
1.96k
            src += payLength + MESSAGE_HEADER;
396
1.96k
            length -= (unsigned int) (payLength + MESSAGE_HEADER);
397
1.96k
            wState->state.spillLength = 0;
398
1.96k
            return false;
399
2.21k
        } else {
400
1.19k
            wState->state.spillLength = 0;
401
1.19k
            wState->state.wantsHead = false;
402
1.19k
            wState->remainingBytes = (unsigned int) (payLength - length + MESSAGE_HEADER);
403
1.19k
            bool fin = isFin(src);
404
1.19k
            if constexpr (isServer) {
405
1.19k
                memcpy(wState->mask, src + MESSAGE_HEADER - 4, 4);
406
1.19k
                uint64_t mask;
407
1.19k
                memcpy(&mask, src + MESSAGE_HEADER - 4, 4);
408
1.19k
                memcpy(((char *)&mask) + 4, src + MESSAGE_HEADER - 4, 4);
409
1.19k
                unmaskImprecise8<0>(src + MESSAGE_HEADER, mask, length);
410
1.19k
                rotateMask(4 - (length - MESSAGE_HEADER) % 4, wState->mask);
411
1.19k
            }
412
1.19k
            Impl::handleFragment(src + MESSAGE_HEADER, length - MESSAGE_HEADER, wState->remainingBytes, wState->state.opCode[wState->state.opStack], fin, wState, user);
413
1.19k
            return true;
414
1.19k
        }
415
3.40k
    }
416
417
    /* This one is nicely vectorized on both ARM64 and X64 - especially with -mavx */
418
0
    static inline void unmaskAll(char * __restrict data, char * __restrict mask) {
419
0
        for (int i = 0; i < LIBUS_RECV_BUFFER_LENGTH; i += 16) {
420
0
            UnrolledXor<16>(data + i, mask);
421
0
        }
422
0
    }
Unexecuted instantiation: uWS::WebSocketProtocol<true, Impl>::unmaskAll(char*, char*)
Unexecuted instantiation: EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::unmaskAll(char*, char*)
Unexecuted instantiation: EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskAll(char*, char*)
Unexecuted instantiation: EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::unmaskAll(char*, char*)
423
424
77.7k
    static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
425
77.7k
        if (wState->remainingBytes <= length) {
426
31.5k
            if (isServer) {
427
31.5k
                unsigned int n = wState->remainingBytes >> 2;
428
31.5k
                unmaskInplace(src, src + n * 4, wState->mask);
429
73.8k
                for (unsigned int i = 0, s = wState->remainingBytes % 4; i < s; i++) {
430
42.3k
                    src[n * 4 + i] ^= wState->mask[i];
431
42.3k
                }
432
31.5k
            }
433
434
31.5k
            if (Impl::handleFragment(src, wState->remainingBytes, 0, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
435
9.96k
                return false;
436
9.96k
            }
437
438
21.6k
            if (wState->state.lastFin) {
439
17.6k
                wState->state.opStack--;
440
17.6k
            }
441
442
21.6k
            src += wState->remainingBytes;
443
21.6k
            length -= wState->remainingBytes;
444
21.6k
            wState->state.wantsHead = true;
445
21.6k
            return true;
446
46.1k
        } else {
447
46.1k
            if (isServer) {
448
                /* No need to unmask if mask is 0 */
449
46.1k
                uint32_t nullmask = 0;
450
46.1k
                if (memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
451
43.5k
                    if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) {
452
0
                        unmaskAll(src, wState->mask);
453
43.5k
                    } else {
454
                        // Slow path
455
43.5k
                        unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
456
43.5k
                    }
457
43.5k
                }
458
46.1k
            }
459
460
46.1k
            wState->remainingBytes -= length;
461
46.1k
            if (Impl::handleFragment(src, length, wState->remainingBytes, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
462
1.39k
                return false;
463
1.39k
            }
464
465
44.7k
            if (isServer && length % 4) {
466
42.4k
                rotateMask(4 - (length % 4), wState->mask);
467
42.4k
            }
468
44.7k
            return false;
469
46.1k
        }
470
77.7k
    }
uWS::WebSocketProtocol<true, Impl>::consumeContinuation(char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
424
16.9k
    static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
425
16.9k
        if (wState->remainingBytes <= length) {
426
12.1k
            if (isServer) {
427
12.1k
                unsigned int n = wState->remainingBytes >> 2;
428
12.1k
                unmaskInplace(src, src + n * 4, wState->mask);
429
25.3k
                for (unsigned int i = 0, s = wState->remainingBytes % 4; i < s; i++) {
430
13.1k
                    src[n * 4 + i] ^= wState->mask[i];
431
13.1k
                }
432
12.1k
            }
433
434
12.1k
            if (Impl::handleFragment(src, wState->remainingBytes, 0, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
435
3.55k
                return false;
436
3.55k
            }
437
438
8.59k
            if (wState->state.lastFin) {
439
6.92k
                wState->state.opStack--;
440
6.92k
            }
441
442
8.59k
            src += wState->remainingBytes;
443
8.59k
            length -= wState->remainingBytes;
444
8.59k
            wState->state.wantsHead = true;
445
8.59k
            return true;
446
12.1k
        } else {
447
4.82k
            if (isServer) {
448
                /* No need to unmask if mask is 0 */
449
4.82k
                uint32_t nullmask = 0;
450
4.82k
                if (memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
451
3.54k
                    if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) {
452
0
                        unmaskAll(src, wState->mask);
453
3.54k
                    } else {
454
                        // Slow path
455
3.54k
                        unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
456
3.54k
                    }
457
3.54k
                }
458
4.82k
            }
459
460
4.82k
            wState->remainingBytes -= length;
461
4.82k
            if (Impl::handleFragment(src, length, wState->remainingBytes, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
462
707
                return false;
463
707
            }
464
465
4.11k
            if (isServer && length % 4) {
466
3.00k
                rotateMask(4 - (length % 4), wState->mask);
467
3.00k
            }
468
4.11k
            return false;
469
4.82k
        }
470
16.9k
    }
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::consumeContinuation(char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
424
8.93k
    static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
425
8.93k
        if (wState->remainingBytes <= length) {
426
6.61k
            if (isServer) {
427
6.61k
                unsigned int n = wState->remainingBytes >> 2;
428
6.61k
                unmaskInplace(src, src + n * 4, wState->mask);
429
15.3k
                for (unsigned int i = 0, s = wState->remainingBytes % 4; i < s; i++) {
430
8.76k
                    src[n * 4 + i] ^= wState->mask[i];
431
8.76k
                }
432
6.61k
            }
433
434
6.61k
            if (Impl::handleFragment(src, wState->remainingBytes, 0, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
435
2.16k
                return false;
436
2.16k
            }
437
438
4.44k
            if (wState->state.lastFin) {
439
3.85k
                wState->state.opStack--;
440
3.85k
            }
441
442
4.44k
            src += wState->remainingBytes;
443
4.44k
            length -= wState->remainingBytes;
444
4.44k
            wState->state.wantsHead = true;
445
4.44k
            return true;
446
6.61k
        } else {
447
2.32k
            if (isServer) {
448
                /* No need to unmask if mask is 0 */
449
2.32k
                uint32_t nullmask = 0;
450
2.32k
                if (memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
451
2.00k
                    if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) {
452
0
                        unmaskAll(src, wState->mask);
453
2.00k
                    } else {
454
                        // Slow path
455
2.00k
                        unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
456
2.00k
                    }
457
2.00k
                }
458
2.32k
            }
459
460
2.32k
            wState->remainingBytes -= length;
461
2.32k
            if (Impl::handleFragment(src, length, wState->remainingBytes, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
462
232
                return false;
463
232
            }
464
465
2.08k
            if (isServer && length % 4) {
466
1.83k
                rotateMask(4 - (length % 4), wState->mask);
467
1.83k
            }
468
2.08k
            return false;
469
2.32k
        }
470
8.93k
    }
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeContinuation(char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
424
43.4k
    static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
425
43.4k
        if (wState->remainingBytes <= length) {
426
6.31k
            if (isServer) {
427
6.31k
                unsigned int n = wState->remainingBytes >> 2;
428
6.31k
                unmaskInplace(src, src + n * 4, wState->mask);
429
16.0k
                for (unsigned int i = 0, s = wState->remainingBytes % 4; i < s; i++) {
430
9.77k
                    src[n * 4 + i] ^= wState->mask[i];
431
9.77k
                }
432
6.31k
            }
433
434
6.31k
            if (Impl::handleFragment(src, wState->remainingBytes, 0, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
435
1.97k
                return false;
436
1.97k
            }
437
438
4.33k
            if (wState->state.lastFin) {
439
3.24k
                wState->state.opStack--;
440
3.24k
            }
441
442
4.33k
            src += wState->remainingBytes;
443
4.33k
            length -= wState->remainingBytes;
444
4.33k
            wState->state.wantsHead = true;
445
4.33k
            return true;
446
37.1k
        } else {
447
37.1k
            if (isServer) {
448
                /* No need to unmask if mask is 0 */
449
37.1k
                uint32_t nullmask = 0;
450
37.1k
                if (memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
451
36.5k
                    if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) {
452
0
                        unmaskAll(src, wState->mask);
453
36.5k
                    } else {
454
                        // Slow path
455
36.5k
                        unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
456
36.5k
                    }
457
36.5k
                }
458
37.1k
            }
459
460
37.1k
            wState->remainingBytes -= length;
461
37.1k
            if (Impl::handleFragment(src, length, wState->remainingBytes, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
462
112
                return false;
463
112
            }
464
465
36.9k
            if (isServer && length % 4) {
466
36.5k
                rotateMask(4 - (length % 4), wState->mask);
467
36.5k
            }
468
36.9k
            return false;
469
37.1k
        }
470
43.4k
    }
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consumeContinuation(char*&, unsigned int&, uWS::WebSocketState<true>*, void*)
Line
Count
Source
424
8.38k
    static inline bool consumeContinuation(char *&src, unsigned int &length, WebSocketState<isServer> *wState, void *user) {
425
8.38k
        if (wState->remainingBytes <= length) {
426
6.50k
            if (isServer) {
427
6.50k
                unsigned int n = wState->remainingBytes >> 2;
428
6.50k
                unmaskInplace(src, src + n * 4, wState->mask);
429
17.1k
                for (unsigned int i = 0, s = wState->remainingBytes % 4; i < s; i++) {
430
10.6k
                    src[n * 4 + i] ^= wState->mask[i];
431
10.6k
                }
432
6.50k
            }
433
434
6.50k
            if (Impl::handleFragment(src, wState->remainingBytes, 0, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
435
2.26k
                return false;
436
2.26k
            }
437
438
4.23k
            if (wState->state.lastFin) {
439
3.63k
                wState->state.opStack--;
440
3.63k
            }
441
442
4.23k
            src += wState->remainingBytes;
443
4.23k
            length -= wState->remainingBytes;
444
4.23k
            wState->state.wantsHead = true;
445
4.23k
            return true;
446
6.50k
        } else {
447
1.87k
            if (isServer) {
448
                /* No need to unmask if mask is 0 */
449
1.87k
                uint32_t nullmask = 0;
450
1.87k
                if (memcmp(wState->mask, &nullmask, sizeof(uint32_t))) {
451
1.48k
                    if /*constexpr*/ (LIBUS_RECV_BUFFER_LENGTH == length) {
452
0
                        unmaskAll(src, wState->mask);
453
1.48k
                    } else {
454
                        // Slow path
455
1.48k
                        unmaskInplace(src, src + ((length >> 2) + 1) * 4, wState->mask);
456
1.48k
                    }
457
1.48k
                }
458
1.87k
            }
459
460
1.87k
            wState->remainingBytes -= length;
461
1.87k
            if (Impl::handleFragment(src, length, wState->remainingBytes, wState->state.opCode[wState->state.opStack], wState->state.lastFin, wState, user)) {
462
344
                return false;
463
344
            }
464
465
1.53k
            if (isServer && length % 4) {
466
1.10k
                rotateMask(4 - (length % 4), wState->mask);
467
1.10k
            }
468
1.53k
            return false;
469
1.87k
        }
470
8.38k
    }
471
472
public:
473
    WebSocketProtocol() {
474
475
    }
476
477
400k
    static inline void consume(char *src, unsigned int length, WebSocketState<isServer> *wState, void *user) {
478
400k
        if (wState->state.spillLength) {
479
40.6k
            src -= wState->state.spillLength;
480
40.6k
            length += wState->state.spillLength;
481
40.6k
            memcpy(src, wState->state.spill, wState->state.spillLength);
482
40.6k
        }
483
400k
        if (wState->state.wantsHead) {
484
344k
            parseNext:
485
1.54M
            while (length >= SHORT_MESSAGE_HEADER) {
486
487
                // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
488
1.50M
                if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
489
1.31M
                    getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
490
201k
                    Impl::forceClose(wState, user, ERR_PROTOCOL);
491
201k
                    return;
492
201k
                }
493
494
1.29M
                if (payloadLength(src) < 126) {
495
1.25M
                    if (consumeMessage<SHORT_MESSAGE_HEADER, uint8_t>(payloadLength(src), src, length, wState, user)) {
496
75.1k
                        return;
497
75.1k
                    }
498
1.25M
                } else if (payloadLength(src) == 126) {
499
25.8k
                    if (length < MEDIUM_MESSAGE_HEADER) {
500
1.26k
                        break;
501
24.5k
                    } else if(consumeMessage<MEDIUM_MESSAGE_HEADER, uint16_t>(protocol::cond_byte_swap<uint16_t>(protocol::bit_cast<uint16_t>(src + 2)), src, length, wState, user)) {
502
10.7k
                        return;
503
10.7k
                    }
504
25.8k
                } else if (length < LONG_MESSAGE_HEADER) {
505
1.36k
                    break;
506
16.2k
                } else if (consumeMessage<LONG_MESSAGE_HEADER, uint64_t>(protocol::cond_byte_swap<uint64_t>(protocol::bit_cast<uint64_t>(src + 2)), src, length, wState, user)) {
507
10.4k
                    return;
508
10.4k
                }
509
1.29M
            }
510
47.2k
            if (length) {
511
17.9k
                memcpy(wState->state.spill, src, length);
512
17.9k
                wState->state.spillLength = length & 0xf;
513
17.9k
            }
514
77.7k
        } else if (consumeContinuation(src, length, wState, user)) {
515
21.6k
            goto parseNext;
516
21.6k
        }
517
400k
    }
uWS::WebSocketProtocol<true, Impl>::consume(char*, unsigned int, uWS::WebSocketState<true>*, void*)
Line
Count
Source
477
184k
    static inline void consume(char *src, unsigned int length, WebSocketState<isServer> *wState, void *user) {
478
184k
        if (wState->state.spillLength) {
479
30.0k
            src -= wState->state.spillLength;
480
30.0k
            length += wState->state.spillLength;
481
30.0k
            memcpy(src, wState->state.spill, wState->state.spillLength);
482
30.0k
        }
483
184k
        if (wState->state.wantsHead) {
484
176k
            parseNext:
485
223k
            while (length >= SHORT_MESSAGE_HEADER) {
486
487
                // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
488
221k
                if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
489
151k
                    getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
490
151k
                    Impl::forceClose(wState, user, ERR_PROTOCOL);
491
151k
                    return;
492
151k
                }
493
494
69.0k
                if (payloadLength(src) < 126) {
495
59.2k
                    if (consumeMessage<SHORT_MESSAGE_HEADER, uint8_t>(payloadLength(src), src, length, wState, user)) {
496
15.3k
                        return;
497
15.3k
                    }
498
59.2k
                } else if (payloadLength(src) == 126) {
499
5.44k
                    if (length < MEDIUM_MESSAGE_HEADER) {
500
287
                        break;
501
5.15k
                    } else if(consumeMessage<MEDIUM_MESSAGE_HEADER, uint16_t>(protocol::cond_byte_swap<uint16_t>(protocol::bit_cast<uint16_t>(src + 2)), src, length, wState, user)) {
502
2.78k
                        return;
503
2.78k
                    }
504
5.44k
                } else if (length < LONG_MESSAGE_HEADER) {
505
276
                    break;
506
4.01k
                } else if (consumeMessage<LONG_MESSAGE_HEADER, uint64_t>(protocol::cond_byte_swap<uint64_t>(protocol::bit_cast<uint64_t>(src + 2)), src, length, wState, user)) {
507
3.00k
                    return;
508
3.00k
                }
509
69.0k
            }
510
3.09k
            if (length) {
511
1.98k
                memcpy(wState->state.spill, src, length);
512
1.98k
                wState->state.spillLength = length & 0xf;
513
1.98k
            }
514
16.9k
        } else if (consumeContinuation(src, length, wState, user)) {
515
8.59k
            goto parseNext;
516
8.59k
        }
517
184k
    }
EpollEchoServerPubSub.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<true, true, test()::PerSocketData> >::consume(char*, unsigned int, uWS::WebSocketState<true>*, void*)
Line
Count
Source
477
84.8k
    static inline void consume(char *src, unsigned int length, WebSocketState<isServer> *wState, void *user) {
478
84.8k
        if (wState->state.spillLength) {
479
4.98k
            src -= wState->state.spillLength;
480
4.98k
            length += wState->state.spillLength;
481
4.98k
            memcpy(src, wState->state.spill, wState->state.spillLength);
482
4.98k
        }
483
84.8k
        if (wState->state.wantsHead) {
484
80.3k
            parseNext:
485
1.10M
            while (length >= SHORT_MESSAGE_HEADER) {
486
487
                // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
488
1.09M
                if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
489
1.06M
                    getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
490
33.3k
                    Impl::forceClose(wState, user, ERR_PROTOCOL);
491
33.3k
                    return;
492
33.3k
                }
493
494
1.06M
                if (payloadLength(src) < 126) {
495
1.05M
                    if (consumeMessage<SHORT_MESSAGE_HEADER, uint8_t>(payloadLength(src), src, length, wState, user)) {
496
30.6k
                        return;
497
30.6k
                    }
498
1.05M
                } else if (payloadLength(src) == 126) {
499
5.12k
                    if (length < MEDIUM_MESSAGE_HEADER) {
500
200
                        break;
501
4.92k
                    } else if(consumeMessage<MEDIUM_MESSAGE_HEADER, uint16_t>(protocol::cond_byte_swap<uint16_t>(protocol::bit_cast<uint16_t>(src + 2)), src, length, wState, user)) {
502
2.50k
                        return;
503
2.50k
                    }
504
5.12k
                } else if (length < LONG_MESSAGE_HEADER) {
505
313
                    break;
506
4.09k
                } else if (consumeMessage<LONG_MESSAGE_HEADER, uint64_t>(protocol::cond_byte_swap<uint64_t>(protocol::bit_cast<uint64_t>(src + 2)), src, length, wState, user)) {
507
2.42k
                    return;
508
2.42k
                }
509
1.06M
            }
510
11.3k
            if (length) {
511
8.20k
                memcpy(wState->state.spill, src, length);
512
8.20k
                wState->state.spillLength = length & 0xf;
513
8.20k
            }
514
11.3k
        } else if (consumeContinuation(src, length, wState, user)) {
515
4.44k
            goto parseNext;
516
4.44k
        }
517
84.8k
    }
EpollHelloWorld.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consume(char*, unsigned int, uWS::WebSocketState<true>*, void*)
Line
Count
Source
477
63.8k
    static inline void consume(char *src, unsigned int length, WebSocketState<isServer> *wState, void *user) {
478
63.8k
        if (wState->state.spillLength) {
479
2.55k
            src -= wState->state.spillLength;
480
2.55k
            length += wState->state.spillLength;
481
2.55k
            memcpy(src, wState->state.spill, wState->state.spillLength);
482
2.55k
        }
483
63.8k
        if (wState->state.wantsHead) {
484
24.7k
            parseNext:
485
51.7k
            while (length >= SHORT_MESSAGE_HEADER) {
486
487
                // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
488
48.2k
                if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
489
46.4k
                    getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
490
2.59k
                    Impl::forceClose(wState, user, ERR_PROTOCOL);
491
2.59k
                    return;
492
2.59k
                }
493
494
45.6k
                if (payloadLength(src) < 126) {
495
36.8k
                    if (consumeMessage<SHORT_MESSAGE_HEADER, uint8_t>(payloadLength(src), src, length, wState, user)) {
496
13.1k
                        return;
497
13.1k
                    }
498
36.8k
                } else if (payloadLength(src) == 126) {
499
4.78k
                    if (length < MEDIUM_MESSAGE_HEADER) {
500
222
                        break;
501
4.56k
                    } else if(consumeMessage<MEDIUM_MESSAGE_HEADER, uint16_t>(protocol::cond_byte_swap<uint16_t>(protocol::bit_cast<uint16_t>(src + 2)), src, length, wState, user)) {
502
2.57k
                        return;
503
2.57k
                    }
504
4.78k
                } else if (length < LONG_MESSAGE_HEADER) {
505
266
                    break;
506
3.71k
                } else if (consumeMessage<LONG_MESSAGE_HEADER, uint64_t>(protocol::cond_byte_swap<uint64_t>(protocol::bit_cast<uint64_t>(src + 2)), src, length, wState, user)) {
507
2.48k
                    return;
508
2.48k
                }
509
45.6k
            }
510
3.95k
            if (length) {
511
2.89k
                memcpy(wState->state.spill, src, length);
512
2.89k
                wState->state.spillLength = length & 0xf;
513
2.89k
            }
514
43.4k
        } else if (consumeContinuation(src, length, wState, user)) {
515
4.33k
            goto parseNext;
516
4.33k
        }
517
63.8k
    }
EpollEchoServer.cpp:uWS::WebSocketProtocol<true, uWS::WebSocketContext<false, true, test()::PerSocketData> >::consume(char*, unsigned int, uWS::WebSocketState<true>*, void*)
Line
Count
Source
477
67.5k
    static inline void consume(char *src, unsigned int length, WebSocketState<isServer> *wState, void *user) {
478
67.5k
        if (wState->state.spillLength) {
479
3.04k
            src -= wState->state.spillLength;
480
3.04k
            length += wState->state.spillLength;
481
3.04k
            memcpy(src, wState->state.spill, wState->state.spillLength);
482
3.04k
        }
483
67.5k
        if (wState->state.wantsHead) {
484
63.3k
            parseNext:
485
163k
            while (length >= SHORT_MESSAGE_HEADER) {
486
487
                // invalid reserved bits / invalid opcodes / invalid control frames / set compressed frame
488
135k
                if ((rsv1(src) && !Impl::setCompressed(wState, user)) || rsv23(src) || (getOpCode(src) > 2 && getOpCode(src) < 8) ||
489
124k
                    getOpCode(src) > 10 || (getOpCode(src) > 2 && (!isFin(src) || payloadLength(src) > 125))) {
490
13.1k
                    Impl::forceClose(wState, user, ERR_PROTOCOL);
491
13.1k
                    return;
492
13.1k
                }
493
494
122k
                if (payloadLength(src) < 126) {
495
106k
                    if (consumeMessage<SHORT_MESSAGE_HEADER, uint8_t>(payloadLength(src), src, length, wState, user)) {
496
15.9k
                        return;
497
15.9k
                    }
498
106k
                } else if (payloadLength(src) == 126) {
499
10.5k
                    if (length < MEDIUM_MESSAGE_HEADER) {
500
554
                        break;
501
9.95k
                    } else if(consumeMessage<MEDIUM_MESSAGE_HEADER, uint16_t>(protocol::cond_byte_swap<uint16_t>(protocol::bit_cast<uint16_t>(src + 2)), src, length, wState, user)) {
502
2.93k
                        return;
503
2.93k
                    }
504
10.5k
                } else if (length < LONG_MESSAGE_HEADER) {
505
506
                    break;
506
4.45k
                } else if (consumeMessage<LONG_MESSAGE_HEADER, uint64_t>(protocol::cond_byte_swap<uint64_t>(protocol::bit_cast<uint64_t>(src + 2)), src, length, wState, user)) {
507
2.48k
                    return;
508
2.48k
                }
509
122k
            }
510
28.8k
            if (length) {
511
4.86k
                memcpy(wState->state.spill, src, length);
512
4.86k
                wState->state.spillLength = length & 0xf;
513
4.86k
            }
514
28.8k
        } else if (consumeContinuation(src, length, wState, user)) {
515
4.23k
            goto parseNext;
516
4.23k
        }
517
67.5k
    }
518
519
    static const int CONSUME_POST_PADDING = 4;
520
    static const int CONSUME_PRE_PADDING = LONG_MESSAGE_HEADER - 1;
521
};
522
523
}
524
525
#endif // UWS_WEBSOCKETPROTOCOL_H