| 8799 | } |
| 8800 | |
| 8801 | inline void url_search_params::sort() { |
| 8802 | // We rely on the fact that the content is valid UTF-8. |
| 8803 | std::ranges::stable_sort(params, [](const key_value_pair &lhs, |
| 8804 | const key_value_pair &rhs) { |
| 8805 | size_t i = 0, j = 0; |
| 8806 | uint32_t low_surrogate1 = 0, low_surrogate2 = 0; |
| 8807 | while ((i < lhs.first.size() || low_surrogate1 != 0) && |
| 8808 | (j < rhs.first.size() || low_surrogate2 != 0)) { |
| 8809 | uint32_t codePoint1 = 0, codePoint2 = 0; |
| 8810 | |
| 8811 | if (low_surrogate1 != 0) { |
| 8812 | codePoint1 = low_surrogate1; |
| 8813 | low_surrogate1 = 0; |
| 8814 | } else { |
| 8815 | uint8_t c1 = uint8_t(lhs.first[i]); |
| 8816 | if (c1 <= 0x7F) { |
| 8817 | codePoint1 = c1; |
| 8818 | i++; |
| 8819 | } else if (c1 <= 0xDF) { |
| 8820 | codePoint1 = ((c1 & 0x1F) << 6) | (uint8_t(lhs.first[i + 1]) & 0x3F); |
| 8821 | i += 2; |
| 8822 | } else if (c1 <= 0xEF) { |
| 8823 | codePoint1 = ((c1 & 0x0F) << 12) | |
| 8824 | ((uint8_t(lhs.first[i + 1]) & 0x3F) << 6) | |
| 8825 | (uint8_t(lhs.first[i + 2]) & 0x3F); |
| 8826 | i += 3; |
| 8827 | } else { |
| 8828 | codePoint1 = ((c1 & 0x07) << 18) | |
| 8829 | ((uint8_t(lhs.first[i + 1]) & 0x3F) << 12) | |
| 8830 | ((uint8_t(lhs.first[i + 2]) & 0x3F) << 6) | |
| 8831 | (uint8_t(lhs.first[i + 3]) & 0x3F); |
| 8832 | i += 4; |
| 8833 | |
| 8834 | codePoint1 -= 0x10000; |
| 8835 | uint16_t high_surrogate = uint16_t(0xD800 + (codePoint1 >> 10)); |
| 8836 | low_surrogate1 = uint16_t(0xDC00 + (codePoint1 & 0x3FF)); |
| 8837 | codePoint1 = high_surrogate; |
| 8838 | } |
| 8839 | } |
| 8840 | |
| 8841 | if (low_surrogate2 != 0) { |
| 8842 | codePoint2 = low_surrogate2; |
| 8843 | low_surrogate2 = 0; |
| 8844 | } else { |
| 8845 | uint8_t c2 = uint8_t(rhs.first[j]); |
| 8846 | if (c2 <= 0x7F) { |
| 8847 | codePoint2 = c2; |
| 8848 | j++; |
| 8849 | } else if (c2 <= 0xDF) { |
| 8850 | codePoint2 = ((c2 & 0x1F) << 6) | (uint8_t(rhs.first[j + 1]) & 0x3F); |
| 8851 | j += 2; |
| 8852 | } else if (c2 <= 0xEF) { |
| 8853 | codePoint2 = ((c2 & 0x0F) << 12) | |
| 8854 | ((uint8_t(rhs.first[j + 1]) & 0x3F) << 6) | |
| 8855 | (uint8_t(rhs.first[j + 2]) & 0x3F); |
| 8856 | j += 3; |
| 8857 | } else { |
| 8858 | codePoint2 = ((c2 & 0x07) << 18) | |