|
19 | 19 | #include <vector> |
20 | 20 | #include <algorithm> |
21 | 21 | #include <cctype> |
| 22 | +#include <cstddef> |
22 | 23 |
|
23 | 24 | /** |
24 | 25 | * @brief Small string helpers (trim, case transform, prefix/suffix checks, split/join). |
@@ -286,6 +287,63 @@ namespace vix::utils |
286 | 287 | return out; |
287 | 288 | } |
288 | 289 |
|
| 290 | + inline bool starts_with_icase(std::string_view s, std::string_view prefix) |
| 291 | + { |
| 292 | + if (s.size() < prefix.size()) |
| 293 | + return false; |
| 294 | + |
| 295 | + for (std::size_t i = 0; i < prefix.size(); ++i) |
| 296 | + { |
| 297 | + unsigned char a = static_cast<unsigned char>(s[i]); |
| 298 | + unsigned char b = static_cast<unsigned char>(prefix[i]); |
| 299 | + |
| 300 | + if (a >= 'A' && a <= 'Z') |
| 301 | + a = static_cast<unsigned char>(a - 'A' + 'a'); |
| 302 | + if (b >= 'A' && b <= 'Z') |
| 303 | + b = static_cast<unsigned char>(b - 'A' + 'a'); |
| 304 | + |
| 305 | + if (a != b) |
| 306 | + return false; |
| 307 | + } |
| 308 | + return true; |
| 309 | + } |
| 310 | + |
| 311 | + inline std::string extract_boundary(std::string_view ct) |
| 312 | + { |
| 313 | + // "multipart/form-data; boundary=----WebKitFormBoundaryabc" |
| 314 | + auto pos = ct.find("boundary="); |
| 315 | + if (pos == std::string_view::npos) |
| 316 | + return {}; |
| 317 | + |
| 318 | + pos += std::string_view("boundary=").size(); |
| 319 | + if (pos >= ct.size()) |
| 320 | + return {}; |
| 321 | + |
| 322 | + std::string_view b = ct.substr(pos); |
| 323 | + |
| 324 | + while (!b.empty() && (b.front() == ' ' || b.front() == '\t')) |
| 325 | + b.remove_prefix(1); |
| 326 | + |
| 327 | + if (!b.empty() && b.front() == '"') |
| 328 | + { |
| 329 | + b.remove_prefix(1); |
| 330 | + auto endq = b.find('"'); |
| 331 | + if (endq != std::string_view::npos) |
| 332 | + b = b.substr(0, endq); |
| 333 | + } |
| 334 | + else |
| 335 | + { |
| 336 | + auto semi = b.find(';'); |
| 337 | + if (semi != std::string_view::npos) |
| 338 | + b = b.substr(0, semi); |
| 339 | + } |
| 340 | + |
| 341 | + while (!b.empty() && (b.back() == ' ' || b.back() == '\t')) |
| 342 | + b.remove_suffix(1); |
| 343 | + |
| 344 | + return std::string(b); |
| 345 | + } |
| 346 | + |
289 | 347 | } // namespace vix::utils |
290 | 348 |
|
291 | 349 | #endif // VIX_STRING_HPP |
0 commit comments