_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEEC2Ev:
 1101|    605|  insertion_ordered_multimap() = default;
_ZN7httplib6detail16parse_query_textEPKcmRNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS4_8equal_toISA_EEEE:
 8483|    605|                             Params &params) {
 8484|    605|  std::set<std::string> cache;
 8485|    605|  split(data, data + size, '&', [&](const char *b, const char *e) {
 8486|    605|    std::string kv(b, e);
 8487|    605|    if (cache.find(kv) != cache.end()) { return; }
 8488|    605|    cache.insert(std::move(kv));
 8489|       |
 8490|    605|    std::string key;
 8491|    605|    std::string val;
 8492|    605|    divide_query_pair(b, e, key, val);
 8493|       |
 8494|    605|    if (!key.empty()) {
 8495|    605|      params.emplace(decode_query_component(key), decode_query_component(val));
 8496|    605|    }
 8497|    605|  });
 8498|    605|}
_ZN7httplib6detail5splitEPKcS2_cNSt3__18functionIFvS2_S2_EEE:
 5762|    926|                  std::function<void(const char *, const char *)> fn) {
 5763|    926|  return split(b, e, d, (std::numeric_limits<size_t>::max)(), std::move(fn));
 5764|    926|}
_ZN7httplib6detail5splitEPKcS2_cmNSt3__18functionIFvS2_S2_EEE:
 5767|    926|                  std::function<void(const char *, const char *)> fn) {
 5768|    926|  size_t i = 0;
 5769|    926|  size_t beg = 0;
 5770|    926|  size_t count = 1;
 5771|       |
 5772|  44.0M|  while (e ? (b + i < e) : (b[i] != '\0')) {
  ------------------
  |  Branch (5772:10): [True: 44.0M, False: 0]
  |  Branch (5772:10): [True: 44.0M, False: 926]
  ------------------
 5773|  44.0M|    if (b[i] == d && count < m) {
  ------------------
  |  Branch (5773:9): [True: 4.50M, False: 39.5M]
  |  Branch (5773:22): [True: 4.50M, False: 0]
  ------------------
 5774|  4.50M|      auto r = trim(b, e, beg, i);
 5775|  4.50M|      if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5775:11): [True: 209k, False: 4.29M]
  ------------------
 5776|  4.50M|      beg = i + 1;
 5777|  4.50M|      count++;
 5778|  4.50M|    }
 5779|  44.0M|    i++;
 5780|  44.0M|  }
 5781|       |
 5782|    926|  if (i) {
  ------------------
  |  Branch (5782:7): [True: 926, False: 0]
  ------------------
 5783|    926|    auto r = trim(b, e, beg, i);
 5784|    926|    if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
  ------------------
  |  Branch (5784:9): [True: 830, False: 96]
  ------------------
 5785|    926|  }
 5786|    926|}
_ZN7httplib6detail4trimEPKcS2_mm:
 5718|  4.50M|                                      size_t right) {
 5719|  6.60M|  while (b + left < e && is_space_or_tab(b[left])) {
  ------------------
  |  Branch (5719:10): [True: 6.60M, False: 96]
  |  Branch (5719:26): [True: 2.10M, False: 4.50M]
  ------------------
 5720|  2.10M|    left++;
 5721|  2.10M|  }
 5722|  6.61M|  while (right > 0 && is_space_or_tab(b[right - 1])) {
  ------------------
  |  Branch (5722:10): [True: 6.60M, False: 65]
  |  Branch (5722:23): [True: 2.10M, False: 4.50M]
  ------------------
 5723|  2.10M|    right--;
 5724|  2.10M|  }
 5725|  4.50M|  return std::make_pair(left, right);
 5726|  4.50M|}
_ZN7httplib6detail15is_space_or_tabEc:
 5573|  13.2M|inline bool is_space_or_tab(char c) { return c == ' ' || c == '\t'; }
  ------------------
  |  Branch (5573:46): [True: 4.17M, False: 9.04M]
  |  Branch (5573:58): [True: 36.4k, False: 9.00M]
  ------------------
_ZZN7httplib6detail16parse_query_textEPKcmRNS0_26insertion_ordered_multimapINSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEENS4_8equal_toISA_EEEEENKUlS2_S2_E_clES2_S2_:
 8485|   179k|  split(data, data + size, '&', [&](const char *b, const char *e) {
 8486|   179k|    std::string kv(b, e);
 8487|   179k|    if (cache.find(kv) != cache.end()) { return; }
  ------------------
  |  Branch (8487:9): [True: 92.4k, False: 87.2k]
  ------------------
 8488|  87.2k|    cache.insert(std::move(kv));
 8489|       |
 8490|  87.2k|    std::string key;
 8491|  87.2k|    std::string val;
 8492|  87.2k|    divide_query_pair(b, e, key, val);
 8493|       |
 8494|  87.2k|    if (!key.empty()) {
  ------------------
  |  Branch (8494:9): [True: 86.7k, False: 564]
  ------------------
 8495|  86.7k|      params.emplace(decode_query_component(key), decode_query_component(val));
 8496|  86.7k|    }
 8497|  87.2k|  });
_ZN7httplib6detail17divide_query_pairEPKcS2_RNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_:
 8473|   118k|                              std::string &val) {
 8474|   118k|  divide(b, static_cast<std::size_t>(e - b), '=',
 8475|   118k|         [&](const char *lhs_data, std::size_t lhs_size, const char *rhs_data,
 8476|   118k|             std::size_t rhs_size) {
 8477|   118k|           key.assign(lhs_data, lhs_size);
 8478|   118k|           val.assign(rhs_data, rhs_size);
 8479|   118k|         });
 8480|   118k|}
_ZN7httplib6detail6divideEPKcmcNSt3__18functionIFvS2_mS2_mEEE:
 5743|   118k|           fn) {
 5744|   118k|  const auto it = std::find(data, data + size, d);
 5745|   118k|  const auto found = static_cast<std::size_t>(it != data + size);
 5746|   118k|  const auto lhs_data = data;
 5747|   118k|  const auto lhs_size = static_cast<std::size_t>(it - data);
 5748|   118k|  const auto rhs_data = it + found;
 5749|   118k|  const auto rhs_size = size - lhs_size - found;
 5750|       |
 5751|   118k|  fn(lhs_data, lhs_size, rhs_data, rhs_size);
 5752|   118k|}
_ZZN7httplib6detail17divide_query_pairEPKcS2_RNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEESA_ENKUlS2_mS2_mE_clES2_mS2_m:
 8476|   118k|             std::size_t rhs_size) {
 8477|   118k|           key.assign(lhs_data, lhs_size);
 8478|   118k|           val.assign(rhs_data, rhs_size);
 8479|   118k|         });
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEE7emplaceIJS8_S8_EEENSB_10iterator_tINS2_4pairIS8_S8_EEEEDpOT_:
 1130|  86.7k|  template <typename... Args> iterator emplace(Args &&...args) {
 1131|  86.7k|    entries_.emplace_back(std::forward<Args>(args)...);
 1132|  86.7k|    return make_iter(entries_.size() - 1, npos());
 1133|  86.7k|  }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEE9make_iterEmm:
 1239|  86.7k|  iterator make_iter(size_type idx, size_type key_idx) {
 1240|  86.7k|    return iterator(entries_.data(), idx, entries_.size(), key_idx);
 1241|  86.7k|  }
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEE10iterator_tINS2_4pairIS8_S8_EEEC2EPSE_mmm:
 1085|  86.7k|        : data_(data), idx_(idx), size_(size), key_idx_(key_idx) {}
_ZN7httplib6detail26insertion_ordered_multimapINSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEENS2_8equal_toIS8_EEE4nposEv:
 1004|  86.7k|  static size_type npos() { return static_cast<size_type>(-1); }
_ZN7httplib22decode_query_componentERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEb:
10727|   231k|                                          bool plus_as_space) {
10728|   231k|  std::string result;
10729|   231k|  result.reserve(component.size());
10730|       |
10731|  39.3M|  for (size_t i = 0; i < component.size(); i++) {
  ------------------
  |  Branch (10731:22): [True: 39.1M, False: 231k]
  ------------------
10732|  39.1M|    if (component[i] == '%' && i + 2 < component.size()) {
  ------------------
  |  Branch (10732:9): [True: 807k, False: 38.2M]
  |  Branch (10732:32): [True: 804k, False: 3.07k]
  ------------------
10733|   804k|      auto val = 0;
10734|   804k|      if (detail::from_hex_to_i(component, i + 1, 2, val)) {
  ------------------
  |  Branch (10734:11): [True: 266k, False: 537k]
  ------------------
10735|   266k|        result += static_cast<char>(val);
10736|   266k|        i += 2;
10737|   537k|      } else {
10738|   537k|        result += component[i];
10739|   537k|      }
10740|  38.3M|    } else if (component[i] == '+' && plus_as_space) {
  ------------------
  |  Branch (10740:16): [True: 15.7k, False: 38.2M]
  |  Branch (10740:39): [True: 15.0k, False: 656]
  ------------------
10741|  15.0k|      result += ' '; // + becomes space in form-urlencoded
10742|  38.2M|    } else {
10743|  38.2M|      result += component[i];
10744|  38.2M|    }
10745|  39.1M|  }
10746|   231k|  return result;
10747|   231k|}
_ZN7httplib6detail13from_hex_to_iERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEmmRi:
 4939|   983k|                          int &val) {
 4940|   983k|  if (i >= s.size()) { return false; }
  ------------------
  |  Branch (4940:7): [True: 9, False: 983k]
  ------------------
 4941|       |
 4942|   983k|  val = 0;
 4943|  1.70M|  for (; cnt; i++, cnt--) {
  ------------------
  |  Branch (4943:10): [True: 1.37M, False: 328k]
  ------------------
 4944|  1.37M|    if (!s[i]) { return false; }
  ------------------
  |  Branch (4944:9): [True: 2.26k, False: 1.37M]
  ------------------
 4945|  1.37M|    auto v = 0;
 4946|  1.37M|    if (is_hex(s[i], v)) {
  ------------------
  |  Branch (4946:9): [True: 721k, False: 652k]
  ------------------
 4947|   721k|      val = val * 16 + v;
 4948|   721k|    } else {
 4949|   652k|      return false;
 4950|   652k|    }
 4951|  1.37M|  }
 4952|   328k|  return true;
 4953|   983k|}
_ZN7httplib6detail6is_hexEcRi:
 4924|  1.37M|inline bool is_hex(char c, int &v) {
 4925|  1.37M|  if (is_ascii_digit(c)) {
  ------------------
  |  Branch (4925:7): [True: 15.3k, False: 1.35M]
  ------------------
 4926|  15.3k|    v = c - '0';
 4927|  15.3k|    return true;
 4928|  1.35M|  } else if ('A' <= c && c <= 'F') {
  ------------------
  |  Branch (4928:14): [True: 973k, False: 386k]
  |  Branch (4928:26): [True: 78.7k, False: 894k]
  ------------------
 4929|  78.7k|    v = c - 'A' + 10;
 4930|  78.7k|    return true;
 4931|  1.28M|  } else if ('a' <= c && c <= 'f') {
  ------------------
  |  Branch (4931:14): [True: 892k, False: 387k]
  |  Branch (4931:26): [True: 627k, False: 265k]
  ------------------
 4932|   627k|    v = c - 'a' + 10;
 4933|   627k|    return true;
 4934|   627k|  }
 4935|   652k|  return false;
 4936|  1.37M|}
_ZN7httplib6detail14is_ascii_digitEc:
  562|  7.76M|inline bool is_ascii_digit(char c) { return '0' <= c && c <= '9'; }
  ------------------
  |  Branch (562:45): [True: 2.53M, False: 5.22M]
  |  Branch (562:57): [True: 1.09M, False: 1.44M]
  ------------------
_ZN7httplib21decode_path_componentERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE:
10634|    238|inline std::string decode_path_component(const std::string &component) {
10635|    238|  std::string result;
10636|    238|  result.reserve(component.size());
10637|       |
10638|  5.00M|  for (size_t i = 0; i < component.size(); i++) {
  ------------------
  |  Branch (10638:22): [True: 5.00M, False: 238]
  ------------------
10639|  5.00M|    if (component[i] == '%' && i + 1 < component.size()) {
  ------------------
  |  Branch (10639:9): [True: 179k, False: 4.82M]
  |  Branch (10639:32): [True: 179k, False: 9]
  ------------------
10640|   179k|      if (component[i + 1] == 'u') {
  ------------------
  |  Branch (10640:11): [True: 5.43k, False: 174k]
  ------------------
10641|       |        // Unicode %uXXXX encoding
10642|  5.43k|        auto val = 0;
10643|  5.43k|        if (detail::from_hex_to_i(component, i + 2, 4, val)) {
  ------------------
  |  Branch (10643:13): [True: 3.80k, False: 1.62k]
  ------------------
10644|       |          // 4 digits Unicode codes: val is 0x0000-0xFFFF (from 4 hex digits),
10645|       |          // so to_utf8 writes at most 3 bytes. buff[4] is safe.
10646|  3.80k|          char buff[4];
10647|  3.80k|          size_t len = detail::to_utf8(val, buff);
10648|  3.80k|          if (len > 0) { result.append(buff, len); }
  ------------------
  |  Branch (10648:15): [True: 2.12k, False: 1.68k]
  ------------------
10649|  3.80k|          i += 5; // 'u0000'
10650|  3.80k|        } else {
10651|  1.62k|          result += component[i];
10652|  1.62k|        }
10653|   174k|      } else {
10654|       |        // Standard %XX encoding
10655|   174k|        auto val = 0;
10656|   174k|        if (detail::from_hex_to_i(component, i + 1, 2, val)) {
  ------------------
  |  Branch (10656:13): [True: 58.1k, False: 116k]
  ------------------
10657|       |          // 2 digits hex codes
10658|  58.1k|          result += static_cast<char>(val);
10659|  58.1k|          i += 2; // 'XX'
10660|   116k|        } else {
10661|   116k|          result += component[i];
10662|   116k|        }
10663|   174k|      }
10664|  4.82M|    } else {
10665|  4.82M|      result += component[i];
10666|  4.82M|    }
10667|  5.00M|  }
10668|    238|  return result;
10669|    238|}
_ZN7httplib6detail7to_utf8EiPc:
 5051|  3.80k|inline size_t to_utf8(int code, char *buff) {
 5052|  3.80k|  if (code < 0x0080) {
  ------------------
  |  Branch (5052:7): [True: 642, False: 3.16k]
  ------------------
 5053|    642|    buff[0] = static_cast<char>(code & 0x7F);
 5054|    642|    return 1;
 5055|  3.16k|  } else if (code < 0x0800) {
  ------------------
  |  Branch (5055:14): [True: 418, False: 2.74k]
  ------------------
 5056|    418|    buff[0] = static_cast<char>(0xC0 | ((code >> 6) & 0x1F));
 5057|    418|    buff[1] = static_cast<char>(0x80 | (code & 0x3F));
 5058|    418|    return 2;
 5059|  2.74k|  } else if (code < 0xD800) {
  ------------------
  |  Branch (5059:14): [True: 808, False: 1.93k]
  ------------------
 5060|    808|    buff[0] = static_cast<char>(0xE0 | ((code >> 12) & 0xF));
 5061|    808|    buff[1] = static_cast<char>(0x80 | ((code >> 6) & 0x3F));
 5062|    808|    buff[2] = static_cast<char>(0x80 | (code & 0x3F));
 5063|    808|    return 3;
 5064|  1.93k|  } else if (code < 0xE000) { // D800 - DFFF is invalid...
  ------------------
  |  Branch (5064:14): [True: 1.68k, False: 253]
  ------------------
 5065|  1.68k|    return 0;
 5066|  1.68k|  } else if (code < 0x10000) {
  ------------------
  |  Branch (5066:14): [True: 253, False: 0]
  ------------------
 5067|    253|    buff[0] = static_cast<char>(0xE0 | ((code >> 12) & 0xF));
 5068|    253|    buff[1] = static_cast<char>(0x80 | ((code >> 6) & 0x3F));
 5069|    253|    buff[2] = static_cast<char>(0x80 | (code & 0x3F));
 5070|    253|    return 3;
 5071|    253|  } else if (code < 0x110000) {
  ------------------
  |  Branch (5071:14): [True: 0, False: 0]
  ------------------
 5072|      0|    buff[0] = static_cast<char>(0xF0 | ((code >> 18) & 0x7));
 5073|      0|    buff[1] = static_cast<char>(0x80 | ((code >> 12) & 0x3F));
 5074|      0|    buff[2] = static_cast<char>(0x80 | ((code >> 6) & 0x3F));
 5075|      0|    buff[3] = static_cast<char>(0x80 | (code & 0x3F));
 5076|      0|    return 4;
 5077|      0|  }
 5078|       |
 5079|       |  // NOTREACHED
 5080|      0|  return 0;
 5081|  3.80k|}
_ZN7httplib22encode_query_componentERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEb:
10672|  31.8k|                                          bool space_as_plus) {
10673|  31.8k|  std::string result;
10674|  31.8k|  result.reserve(component.size() * 3);
10675|       |
10676|  6.42M|  for (size_t i = 0; i < component.size(); i++) {
  ------------------
  |  Branch (10676:22): [True: 6.38M, False: 31.8k]
  ------------------
10677|  6.38M|    auto c = static_cast<unsigned char>(component[i]);
10678|       |
10679|       |    // Unreserved characters per RFC 3986
10680|  6.38M|    if (detail::is_ascii_alnum(static_cast<char>(c)) || c == '-' || c == '.' ||
  ------------------
  |  Branch (10680:9): [True: 1.47M, False: 4.91M]
  |  Branch (10680:57): [True: 7.61k, False: 4.90M]
  |  Branch (10680:69): [True: 38.5k, False: 4.86M]
  ------------------
10681|  4.86M|        c == '_' || c == '~') {
  ------------------
  |  Branch (10681:9): [True: 1.32k, False: 4.86M]
  |  Branch (10681:21): [True: 2.13k, False: 4.86M]
  ------------------
10682|  1.52M|      result += static_cast<char>(c);
10683|  1.52M|    }
10684|       |    // Space handling
10685|  4.86M|    else if (c == ' ') {
  ------------------
  |  Branch (10685:14): [True: 12.2k, False: 4.85M]
  ------------------
10686|  12.2k|      if (space_as_plus) {
  ------------------
  |  Branch (10686:11): [True: 12.2k, False: 0]
  ------------------
10687|  12.2k|        result += '+';
10688|  12.2k|      } else {
10689|      0|        result += "%20";
10690|      0|      }
10691|  12.2k|    }
10692|       |    // Plus sign handling
10693|  4.85M|    else if (c == '+') {
  ------------------
  |  Branch (10693:14): [True: 385, False: 4.85M]
  ------------------
10694|    385|      if (space_as_plus) {
  ------------------
  |  Branch (10694:11): [True: 385, False: 0]
  ------------------
10695|    385|        result += "%2B";
10696|    385|      } else {
10697|      0|        result += static_cast<char>(c);
10698|      0|      }
10699|    385|    }
10700|       |    // Query-safe sub-delimiters (excluding & and = which are query delimiters)
10701|  4.85M|    else if (c == '!' || c == '$' || c == '\'' || c == '(' || c == ')' ||
  ------------------
  |  Branch (10701:14): [True: 4.66k, False: 4.84M]
  |  Branch (10701:26): [True: 1.54k, False: 4.84M]
  |  Branch (10701:38): [True: 1.11k, False: 4.84M]
  |  Branch (10701:51): [True: 1.82k, False: 4.84M]
  |  Branch (10701:63): [True: 3.09k, False: 4.84M]
  ------------------
10702|  4.84M|             c == '*' || c == ',' || c == ';') {
  ------------------
  |  Branch (10702:14): [True: 16.7k, False: 4.82M]
  |  Branch (10702:26): [True: 23.9k, False: 4.79M]
  |  Branch (10702:38): [True: 1.07k, False: 4.79M]
  ------------------
10703|  53.9k|      result += static_cast<char>(c);
10704|  53.9k|    }
10705|       |    // Colon and @ are allowed in query
10706|  4.79M|    else if (c == ':' || c == '@') {
  ------------------
  |  Branch (10706:14): [True: 2.30k, False: 4.79M]
  |  Branch (10706:26): [True: 1.27k, False: 4.79M]
  ------------------
10707|  3.57k|      result += static_cast<char>(c);
10708|  3.57k|    }
10709|       |    // Forward slash is allowed in query values
10710|  4.79M|    else if (c == '/') {
  ------------------
  |  Branch (10710:14): [True: 318k, False: 4.47M]
  ------------------
10711|   318k|      result += static_cast<char>(c);
10712|   318k|    }
10713|       |    // Question mark is allowed in query values (after first ?)
10714|  4.47M|    else if (c == '?') {
  ------------------
  |  Branch (10714:14): [True: 956, False: 4.47M]
  ------------------
10715|    956|      result += static_cast<char>(c);
10716|  4.47M|    } else {
10717|  4.47M|      result += '%';
10718|  4.47M|      char hex[3];
10719|  4.47M|      snprintf(hex, sizeof(hex), "%02X", c);
10720|  4.47M|      result.append(hex, 2);
10721|  4.47M|    }
10722|  6.38M|  }
10723|  31.8k|  return result;
10724|  31.8k|}
_ZN7httplib6detail14is_ascii_alnumEc:
  568|  6.38M|inline bool is_ascii_alnum(char c) {
  569|  6.38M|  return is_ascii_digit(c) || is_ascii_alpha(c);
  ------------------
  |  Branch (569:10): [True: 1.08M, False: 5.30M]
  |  Branch (569:31): [True: 393k, False: 4.91M]
  ------------------
  570|  6.38M|}
_ZN7httplib6detail14is_ascii_alphaEc:
  564|  5.30M|inline bool is_ascii_alpha(char c) {
  565|  5.30M|  return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
  ------------------
  |  Branch (565:11): [True: 177k, False: 5.13M]
  |  Branch (565:23): [True: 167k, False: 10.0k]
  |  Branch (565:37): [True: 276k, False: 4.86M]
  |  Branch (565:49): [True: 225k, False: 50.8k]
  ------------------
  566|  5.30M|}
_ZN7httplib6detail22normalize_query_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 8511|    321|inline std::string normalize_query_string(const std::string &query) {
 8512|    321|  std::string result;
 8513|    321|  split(query.data(), query.data() + query.size(), '&',
 8514|    321|        [&](const char *b, const char *e) {
 8515|    321|          std::string key;
 8516|    321|          std::string val;
 8517|    321|          divide_query_pair(b, e, key, val);
 8518|       |
 8519|    321|          if (!key.empty()) {
 8520|    321|            auto dec_key = decode_query_component(key);
 8521|    321|            auto dec_val = decode_query_component(val);
 8522|       |
 8523|    321|            if (!result.empty()) { result += '&'; }
 8524|    321|            result += encode_query_component(dec_key);
 8525|    321|            if (!val.empty() || std::find(b, e, '=') != e) {
 8526|    321|              result += '=';
 8527|    321|              result += encode_query_component(dec_val);
 8528|    321|            }
 8529|    321|          }
 8530|    321|        });
 8531|    321|  return result;
 8532|    321|}
_ZZN7httplib6detail22normalize_query_stringERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEEENKUlPKcSB_E_clESB_SB_:
 8514|  30.9k|        [&](const char *b, const char *e) {
 8515|  30.9k|          std::string key;
 8516|  30.9k|          std::string val;
 8517|  30.9k|          divide_query_pair(b, e, key, val);
 8518|       |
 8519|  30.9k|          if (!key.empty()) {
  ------------------
  |  Branch (8519:15): [True: 28.9k, False: 2.04k]
  ------------------
 8520|  28.9k|            auto dec_key = decode_query_component(key);
 8521|  28.9k|            auto dec_val = decode_query_component(val);
 8522|       |
 8523|  28.9k|            if (!result.empty()) { result += '&'; }
  ------------------
  |  Branch (8523:17): [True: 28.6k, False: 273]
  ------------------
 8524|  28.9k|            result += encode_query_component(dec_key);
 8525|  28.9k|            if (!val.empty() || std::find(b, e, '=') != e) {
  ------------------
  |  Branch (8525:17): [True: 1.99k, False: 26.9k]
  |  Branch (8525:17): [True: 2.83k, False: 26.1k]
  |  Branch (8525:33): [True: 847, False: 26.1k]
  ------------------
 8526|  2.83k|              result += '=';
 8527|  2.83k|              result += encode_query_component(dec_val);
 8528|  2.83k|            }
 8529|  28.9k|          }
 8530|  30.9k|        });
_ZN7httplib6detail13is_valid_pathERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEE:
 5439|    213|inline bool is_valid_path(const std::string &path) {
 5440|    213|  size_t level = 0;
 5441|    213|  size_t i = 0;
 5442|       |
 5443|       |  // Skip slash
 5444|  1.07M|  while (i < path.size() && path[i] == '/') {
  ------------------
  |  Branch (5444:10): [True: 1.07M, False: 13]
  |  Branch (5444:29): [True: 1.07M, False: 200]
  ------------------
 5445|  1.07M|    i++;
 5446|  1.07M|  }
 5447|       |
 5448|   720k|  while (i < path.size()) {
  ------------------
  |  Branch (5448:10): [True: 720k, False: 201]
  ------------------
 5449|       |    // Read component
 5450|   720k|    auto beg = i;
 5451|  3.72M|    while (i < path.size() && path[i] != '/') {
  ------------------
  |  Branch (5451:12): [True: 3.72M, False: 172]
  |  Branch (5451:31): [True: 3.00M, False: 720k]
  ------------------
 5452|  3.00M|      if (path[i] == '\0') {
  ------------------
  |  Branch (5452:11): [True: 9, False: 3.00M]
  ------------------
 5453|      9|        return false;
 5454|  3.00M|      } else if (path[i] == '\\') {
  ------------------
  |  Branch (5454:18): [True: 2, False: 3.00M]
  ------------------
 5455|      2|        return false;
 5456|      2|      }
 5457|  3.00M|      i++;
 5458|  3.00M|    }
 5459|       |
 5460|   720k|    auto len = i - beg;
 5461|   720k|    assert(len > 0);
  ------------------
  |  Branch (5461:5): [True: 720k, False: 0]
  ------------------
 5462|       |
 5463|   720k|    if (!path.compare(beg, len, ".")) {
  ------------------
  |  Branch (5463:9): [True: 3.95k, False: 716k]
  ------------------
 5464|  3.95k|      ;
 5465|   716k|    } else if (!path.compare(beg, len, "..")) {
  ------------------
  |  Branch (5465:16): [True: 35.0k, False: 681k]
  ------------------
 5466|  35.0k|      if (level == 0) { return false; }
  ------------------
  |  Branch (5466:11): [True: 1, False: 35.0k]
  ------------------
 5467|  35.0k|      level--;
 5468|   681k|    } else {
 5469|   681k|      level++;
 5470|   681k|    }
 5471|       |
 5472|       |    // Skip slash
 5473|  1.61M|    while (i < path.size() && path[i] == '/') {
  ------------------
  |  Branch (5473:12): [True: 1.61M, False: 188]
  |  Branch (5473:31): [True: 895k, False: 720k]
  ------------------
 5474|   895k|      i++;
 5475|   895k|    }
 5476|   720k|  }
 5477|       |
 5478|    201|  return true;
 5479|    213|}

LLVMFuzzerTestOneInput:
    7|  1.55k|extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    8|  1.55k|  if (size < 2) return 0;
  ------------------
  |  Branch (8:7): [True: 1, False: 1.55k]
  ------------------
    9|       |
   10|       |  // Use first byte to select which parsing function to exercise
   11|  1.55k|  uint8_t selector = data[0];
   12|  1.55k|  const char *payload = reinterpret_cast<const char *>(data + 1);
   13|  1.55k|  size_t payload_size = size - 1;
   14|  1.55k|  std::string input(payload, payload_size);
   15|       |
   16|  1.55k|  switch (selector % 6) {
  ------------------
  |  Branch (16:11): [True: 1.55k, False: 0]
  ------------------
   17|    605|  case 0: {
  ------------------
  |  Branch (17:3): [True: 605, False: 952]
  ------------------
   18|       |    // parse_query_text
   19|    605|    httplib::Params params;
   20|    605|    httplib::detail::parse_query_text(payload, payload_size, params);
   21|    605|    break;
   22|      0|  }
   23|     77|  case 1: {
  ------------------
  |  Branch (23:3): [True: 77, False: 1.48k]
  ------------------
   24|       |    // decode_query_component
   25|     77|    httplib::decode_query_component(input, true);
   26|     77|    httplib::decode_query_component(input, false);
   27|     77|    break;
   28|      0|  }
   29|    238|  case 2: {
  ------------------
  |  Branch (29:3): [True: 238, False: 1.31k]
  ------------------
   30|       |    // decode_path_component
   31|    238|    httplib::decode_path_component(input);
   32|    238|    break;
   33|      0|  }
   34|    103|  case 3: {
  ------------------
  |  Branch (34:3): [True: 103, False: 1.45k]
  ------------------
   35|       |    // encode_query_component
   36|    103|    httplib::encode_query_component(input);
   37|    103|    break;
   38|      0|  }
   39|    321|  case 4: {
  ------------------
  |  Branch (39:3): [True: 321, False: 1.23k]
  ------------------
   40|       |    // normalize_query_string
   41|    321|    httplib::detail::normalize_query_string(input);
   42|    321|    break;
   43|      0|  }
   44|    213|  case 5: {
  ------------------
  |  Branch (44:3): [True: 213, False: 1.34k]
  ------------------
   45|       |    // is_valid_path
   46|    213|    httplib::detail::is_valid_path(input);
   47|    213|    break;
   48|      0|  }
   49|  1.55k|  }
   50|       |
   51|  1.55k|  return 0;
   52|  1.55k|}

