@@ -321,13 +321,50 @@ make_unique(std::size_t n) {
321
321
return std::unique_ptr<T>(new RT[n]);
322
322
}
323
323
324
- struct ci {
324
+ inline unsigned char to_lower (int c) {
325
+ const static unsigned char table[256 ] = {
326
+ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 ,
327
+ 15 , 16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 ,
328
+ 30 , 31 , 32 , 33 , 34 , 35 , 36 , 37 , 38 , 39 , 40 , 41 , 42 , 43 , 44 ,
329
+ 45 , 46 , 47 , 48 , 49 , 50 , 51 , 52 , 53 , 54 , 55 , 56 , 57 , 58 , 59 ,
330
+ 60 , 61 , 62 , 63 , 64 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 , 105 , 106 ,
331
+ 107 , 108 , 109 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 , 120 , 121 ,
332
+ 122 , 91 , 92 , 93 , 94 , 95 , 96 , 97 , 98 , 99 , 100 , 101 , 102 , 103 , 104 ,
333
+ 105 , 106 , 107 , 108 , 109 , 110 , 111 , 112 , 113 , 114 , 115 , 116 , 117 , 118 , 119 ,
334
+ 120 , 121 , 122 , 123 , 124 , 125 , 126 , 127 , 128 , 129 , 130 , 131 , 132 , 133 , 134 ,
335
+ 135 , 136 , 137 , 138 , 139 , 140 , 141 , 142 , 143 , 144 , 145 , 146 , 147 , 148 , 149 ,
336
+ 150 , 151 , 152 , 153 , 154 , 155 , 156 , 157 , 158 , 159 , 160 , 161 , 162 , 163 , 164 ,
337
+ 165 , 166 , 167 , 168 , 169 , 170 , 171 , 172 , 173 , 174 , 175 , 176 , 177 , 178 , 179 ,
338
+ 180 , 181 , 182 , 183 , 184 , 185 , 186 , 187 , 188 , 189 , 190 , 191 , 224 , 225 , 226 ,
339
+ 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 , 240 , 241 ,
340
+ 242 , 243 , 244 , 245 , 246 , 215 , 248 , 249 , 250 , 251 , 252 , 253 , 254 , 223 , 224 ,
341
+ 225 , 226 , 227 , 228 , 229 , 230 , 231 , 232 , 233 , 234 , 235 , 236 , 237 , 238 , 239 ,
342
+ 240 , 241 , 242 , 243 , 244 , 245 , 246 , 247 , 248 , 249 , 250 , 251 , 252 , 253 , 254 ,
343
+ 255 ,
344
+ };
345
+ assert (0 <= c && c < 256 );
346
+ return table[c];
347
+ }
348
+
349
+ struct case_ignore_equal {
325
350
bool operator ()(const std::string &s1, const std::string &s2) const {
326
- return std::lexicographical_compare (s1.begin (), s1.end (), s2.begin (),
327
- s2.end (),
328
- [](unsigned char c1, unsigned char c2) {
329
- return ::tolower (c1) < ::tolower (c2);
330
- });
351
+ return s1.size () == s2.size () &&
352
+ std::equal (s1.begin (), s1.end (), s2.begin (), [](char a, char b) {
353
+ return to_lower (a) == to_lower (b);
354
+ });
355
+ }
356
+ };
357
+
358
+ struct case_ignore_hash {
359
+ constexpr size_t operator ()(std::string_view key) const {
360
+ return hash_core (key.data (), key.size (), 0 );
361
+ }
362
+
363
+ constexpr size_t hash_core (const char *s, size_t l, size_t h) const {
364
+ return (l == 0 )
365
+ ? h
366
+ : hash_core (s + 1 , l - 1 ,
367
+ (h * 33 ) ^ static_cast <unsigned char >(to_lower (*s)));
331
368
}
332
369
};
333
370
@@ -436,7 +473,9 @@ enum StatusCode {
436
473
NetworkAuthenticationRequired_511 = 511 ,
437
474
};
438
475
439
- using Headers = std::multimap<std::string, std::string, detail::ci>;
476
+ using Headers =
477
+ std::unordered_multimap<std::string, std::string, detail::case_ignore_hash,
478
+ detail::case_ignore_equal>;
440
479
441
480
using Params = std::multimap<std::string, std::string>;
442
481
using Match = std::smatch;
@@ -4007,7 +4046,7 @@ inline const char *get_header_value(const Headers &headers,
4007
4046
inline bool compare_case_ignore (const std::string &a, const std::string &b) {
4008
4047
if (a.size () != b.size ()) { return false ; }
4009
4048
for (size_t i = 0 ; i < b.size (); i++) {
4010
- if (:: tolower (a[i]) != :: tolower (b[i])) { return false ; }
4049
+ if (to_lower (a[i]) != to_lower (b[i])) { return false ; }
4011
4050
}
4012
4051
return true ;
4013
4052
}
@@ -4822,7 +4861,7 @@ class MultipartFormDataParser {
4822
4861
const std::string &b) const {
4823
4862
if (a.size () < b.size ()) { return false ; }
4824
4863
for (size_t i = 0 ; i < b.size (); i++) {
4825
- if (:: tolower (a[i]) != :: tolower (b[i])) { return false ; }
4864
+ if (to_lower (a[i]) != to_lower (b[i])) { return false ; }
4826
4865
}
4827
4866
return true ;
4828
4867
}
0 commit comments