File Coverage

src/panda/protocol/websocket/HeaderValueParamsParser.cc
Criterion Covered Total %
statement 62 63 98.4
branch 56 88 63.6
condition n/a
subroutine n/a
pod n/a
total 118 151 78.1


line stmt bran cond sub pod time code
1             #include "HeaderValueParamsParser.h"
2              
3             namespace panda { namespace protocol { namespace websocket {
4              
5             static const int MAX_HEADER_VALUE = 8*1024;
6             using uchar = unsigned char;
7             static bool header_value_special[256];
8              
9 18           static int init () {
10 18           header_value_special[(uchar)';'] = true;
11 18           header_value_special[(uchar)','] = true;
12 18           header_value_special[(uchar)'='] = true;
13 18           header_value_special[(uchar)' '] = true;
14 18           return 0;
15             }
16 18           static const auto __init = init();
17              
18              
19 154           void parse_header_value(const string& strval, HeaderValues& values) {
20 154 50         auto cur = strval.begin();
21 154 50         auto end = strval.end();
22              
23 154           enum { PARSE_MODE_NAME, PARSE_MODE_KEY, PARSE_MODE_VAL } mode = PARSE_MODE_NAME;
24             char accstr[MAX_HEADER_VALUE];
25 308           string key;
26 154           char* acc = accstr;
27 154           HeaderValue* elem = NULL;
28              
29 10662 100         for (; cur != end; ++cur) {
30 10508           char c = *cur;
31 10508 100         if (!header_value_special[(uchar)c]) {
32 9656           *acc++ = c;
33 9656           continue;
34             }
35 852 100         if (c == ' ') continue;
36              
37 561 100         if (mode == PARSE_MODE_NAME) {
38 142 50         if (c == ';' || c == ',') {
    0          
39 142           auto sz = values.size();
40 142 50         values.resize(sz+1);
41 142           elem = &values[sz];
42 142 50         elem->name.assign(accstr, acc-accstr);
43 142           acc = accstr;
44 142 50         if (c == ';') mode = PARSE_MODE_KEY;
45             }
46 142           else *acc++ = c;
47             }
48 419 100         else if (mode == PARSE_MODE_KEY) {
49 280 100         if (c == ';' || c == ',') {
    50          
50 7 50         elem->params.emplace(string(accstr, acc-accstr), string());
    50          
51 7           acc = accstr;
52 7 50         if (c == ',') mode = PARSE_MODE_NAME;
53             }
54 273 50         else if (c == '=') {
55 273 50         key.assign(accstr, acc-accstr);
56 273           acc = accstr;
57 273           mode = PARSE_MODE_VAL;
58             }
59 280           else *acc++ = c;
60             }
61             else { // PARSE_MODE_VAL
62 139 100         if (c == ';' || c == ',') {
    50          
63 139 50         elem->params.emplace(key, string(accstr, acc-accstr));
    50          
64 139           acc = accstr;
65 277 100         if (c == ',') mode = PARSE_MODE_NAME;
66 138           else mode = PARSE_MODE_KEY;
67             }
68 0           else *acc++ = c;
69             }
70             }
71              
72             // finish
73 154 100         if (mode == PARSE_MODE_NAME) values.push_back(HeaderValue{string(accstr, acc-accstr), HeaderValueParams()});
    50          
    50          
74 141 100         else if (mode == PARSE_MODE_KEY) elem->params.emplace(string(accstr, acc-accstr), string());
    50          
    50          
75 134 50         else /* PARSE_MODE_VAL */ elem->params.emplace(key, string(accstr, acc-accstr));
    50          
76 154           }
77              
78 168           string compile_header_value(const HeaderValues& values) {
79 168           string str;
80              
81 336 100         for (const auto& elem : values) {
82 168 50         str += elem.name;
83 483 100         for (const auto& param : elem.params) {
84 315 50         str += "; ";
85 315 50         str += param.first;
86 315 100         if (param.second) {
87 300 50         str += '=';
88 300 50         str += param.second;
89             }
90             }
91 168 50         str += ", ";
92             }
93              
94 168 50         if (str) str.length(str.length() - 2);
95              
96 168           return str;
97             }
98              
99 72 50         }}}
    50