| 128 | } |
| 129 | |
| 130 | bool TBaseServerRequestData::Parse(TStringBuf origReq) { |
| 131 | ParseBuf_.reserve(origReq.size() + 16); |
| 132 | ParseBuf_.assign(origReq.begin(), origReq.end()); |
| 133 | ParseBuf_.insert(ParseBuf_.end(), 15, ' '); |
| 134 | ParseBuf_.push_back('\0'); |
| 135 | char* req = ParseBuf_.data(); |
| 136 | |
| 137 | while (*req == ' ' || *req == '\t') |
| 138 | req++; |
| 139 | if (*req != '/') |
| 140 | return false; // we are not a proxy |
| 141 | while (req[1] == '/') // remove redundant slashes |
| 142 | req++; |
| 143 | |
| 144 | char* pathBegin = req; |
| 145 | char* queryBegin = nullptr; |
| 146 | |
| 147 | #ifdef _sse4_2_ |
| 148 | const __m128i simdSpace = _mm_set1_epi8(' '); |
| 149 | const __m128i simdTab = _mm_set1_epi8('\t'); |
| 150 | const __m128i simdHash = _mm_set1_epi8('#'); |
| 151 | const __m128i simdQuestion = _mm_set1_epi8('?'); |
| 152 | |
| 153 | auto isEnd = [=](__m128i x) { |
| 154 | const auto v = _mm_or_si128( |
| 155 | _mm_or_si128( |
| 156 | _mm_cmpeq_epi8(x, simdSpace), _mm_cmpeq_epi8(x, simdTab)), |
| 157 | _mm_cmpeq_epi8(x, simdHash)); |
| 158 | return !_mm_testz_si128(v, v); |
| 159 | }; |
| 160 | |
| 161 | // No need for the range check because we have padding of spaces at the end. |
| 162 | for (;; req += 16) { |
| 163 | const auto x = _mm_loadu_si128(reinterpret_cast<const __m128i *>(req)); |
| 164 | const auto isQuestionSimd = _mm_cmpeq_epi8(x, simdQuestion); |
| 165 | const auto isQuestion = !_mm_testz_si128(isQuestionSimd, isQuestionSimd); |
| 166 | if (isEnd(x)) { |
| 167 | if (isQuestion) { |
| 168 | // The prospective query end and a question sign are both in the |
| 169 | // current block. Need to find out which comes first. |
| 170 | for (;*req != ' ' && *req != '\t' && *req != '#'; ++req) { |
| 171 | if (*req == '?') { |
| 172 | queryBegin = req + 1; |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | } |
| 177 | break; |
| 178 | } |
| 179 | if (isQuestion) { |
| 180 | // Find the exact query beginning |
| 181 | for (queryBegin = req; *queryBegin != '?'; ++queryBegin) { |
| 182 | } |
| 183 | ++queryBegin; |
| 184 | |
| 185 | break; |
| 186 | } |
| 187 | } |
no test coverage detected