@@ -321,6 +321,8 @@ make_unique(std::size_t n) {
321
321
return std::unique_ptr<T>(new RT[n]);
322
322
}
323
323
324
+ namespace case_ignore {
325
+
324
326
inline unsigned char to_lower (int c) {
325
327
const static unsigned char table[256 ] = {
326
328
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,
@@ -345,28 +347,36 @@ inline unsigned char to_lower(int c) {
345
347
return table[(unsigned char )(char )c];
346
348
}
347
349
348
- struct case_ignore_equal {
349
- bool operator ()(const std::string &s1, const std::string &s2) const {
350
- return s1.size () == s2.size () &&
351
- std::equal (s1.begin (), s1.end (), s2.begin (), [](char a, char b) {
352
- return to_lower (a) == to_lower (b);
353
- });
350
+ inline bool equal (const std::string &a, const std::string &b) {
351
+ return a.size () == b.size () &&
352
+ std::equal (a.begin (), a.end (), b.begin (),
353
+ [](char a, char b) { return to_lower (a) == to_lower (b); });
354
+ }
355
+
356
+ struct equal_to {
357
+ bool operator ()(const std::string &a, const std::string &b) const {
358
+ return equal (a, b);
354
359
}
355
360
};
356
361
357
- struct case_ignore_hash {
362
+ struct hash {
358
363
size_t operator ()(const std::string &key) const {
359
364
return hash_core (key.data (), key.size (), 0 );
360
365
}
361
366
362
- constexpr size_t hash_core (const char *s, size_t l, size_t h) const {
363
- return (l == 0 )
364
- ? h
365
- : hash_core (s + 1 , l - 1 ,
366
- (h * 33 ) ^ static_cast <unsigned char >(to_lower (*s)));
367
+ size_t hash_core (const char *s, size_t l, size_t h) const {
368
+ return (l == 0 ) ? h
369
+ : hash_core (s + 1 , l - 1 ,
370
+ // Unsets the 6 high bits of h, therefore no
371
+ // overflow happens
372
+ (((std::numeric_limits<size_t >::max)() >> 6 ) &
373
+ h * 33 ) ^
374
+ static_cast <unsigned char >(to_lower (*s)));
367
375
}
368
376
};
369
377
378
+ }; // namespace case_ignore
379
+
370
380
// This is based on
371
381
// "http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4189".
372
382
@@ -473,8 +483,8 @@ enum StatusCode {
473
483
};
474
484
475
485
using Headers =
476
- std::unordered_multimap<std::string, std::string, detail::case_ignore_hash ,
477
- detail::case_ignore_equal >;
486
+ std::unordered_multimap<std::string, std::string, detail::case_ignore::hash ,
487
+ detail::case_ignore::equal_to >;
478
488
479
489
using Params = std::multimap<std::string, std::string>;
480
490
using Match = std::smatch;
@@ -3996,14 +4006,6 @@ inline const char *get_header_value(const Headers &headers,
3996
4006
return def;
3997
4007
}
3998
4008
3999
- inline bool compare_case_ignore (const std::string &a, const std::string &b) {
4000
- if (a.size () != b.size ()) { return false ; }
4001
- for (size_t i = 0 ; i < b.size (); i++) {
4002
- if (to_lower (a[i]) != to_lower (b[i])) { return false ; }
4003
- }
4004
- return true ;
4005
- }
4006
-
4007
4009
template <typename T>
4008
4010
inline bool parse_header (const char *beg, const char *end, T fn) {
4009
4011
// Skip trailing spaces and tabs.
@@ -4031,7 +4033,7 @@ inline bool parse_header(const char *beg, const char *end, T fn) {
4031
4033
if (!key_len) { return false ; }
4032
4034
4033
4035
auto key = std::string (beg, key_end);
4034
- auto val = compare_case_ignore (key, " Location" )
4036
+ auto val = case_ignore::equal (key, " Location" )
4035
4037
? std::string (p, end)
4036
4038
: decode_url (std::string (p, end), false );
4037
4039
@@ -4196,7 +4198,7 @@ inline bool read_content_chunked(Stream &strm, T &x,
4196
4198
}
4197
4199
4198
4200
inline bool is_chunked_transfer_encoding (const Headers &headers) {
4199
- return compare_case_ignore (
4201
+ return case_ignore::equal (
4200
4202
get_header_value (headers, " Transfer-Encoding" , " " , 0 ), " chunked" );
4201
4203
}
4202
4204
@@ -4835,7 +4837,9 @@ class MultipartFormDataParser {
4835
4837
const std::string &b) const {
4836
4838
if (a.size () < b.size ()) { return false ; }
4837
4839
for (size_t i = 0 ; i < b.size (); i++) {
4838
- if (to_lower (a[i]) != to_lower (b[i])) { return false ; }
4840
+ if (case_ignore::to_lower (a[i]) != case_ignore::to_lower (b[i])) {
4841
+ return false ;
4842
+ }
4839
4843
}
4840
4844
return true ;
4841
4845
}
0 commit comments