File indexing completed on 2025-01-18 09:53:26
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_URL_DETAIL_ENCODE_HPP
0012 #define BOOST_URL_DETAIL_ENCODE_HPP
0013
0014 #include <boost/url/encoding_opts.hpp>
0015 #include <boost/url/pct_string_view.hpp>
0016 #include <boost/url/grammar/hexdig_chars.hpp>
0017 #include <boost/core/ignore_unused.hpp>
0018 #include <cstdlib>
0019
0020 namespace boost {
0021 namespace urls {
0022 namespace detail {
0023
0024 constexpr
0025 char const* const hexdigs[] = {
0026 "0123456789ABCDEF",
0027 "0123456789abcdef" };
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 template<class CharSet>
0038 std::size_t
0039 re_encoded_size_unsafe(
0040 core::string_view s,
0041 CharSet const& unreserved,
0042 encoding_opts opt) noexcept
0043 {
0044 std::size_t n = 0;
0045 auto const end = s.end();
0046 auto it = s.begin();
0047 if(opt.space_as_plus)
0048 {
0049 while(it != end)
0050 {
0051 if(*it != '%')
0052 {
0053 if( unreserved(*it)
0054 || *it == ' ')
0055 n += 1;
0056 else
0057 n += 3;
0058 ++it;
0059 }
0060 else
0061 {
0062 BOOST_ASSERT(end - it >= 3);
0063 BOOST_ASSERT(
0064 grammar::hexdig_value(
0065 it[1]) >= 0);
0066 BOOST_ASSERT(
0067 grammar::hexdig_value(
0068 it[2]) >= 0);
0069 n += 3;
0070 it += 3;
0071 }
0072 }
0073 }
0074 else
0075 {
0076 while(it != end)
0077 {
0078 if(*it != '%')
0079 {
0080 if(unreserved(*it))
0081 n += 1;
0082 else
0083 n += 3;
0084 ++it;
0085 }
0086 else
0087 {
0088 BOOST_ASSERT(end - it >= 3);
0089 BOOST_ASSERT(
0090 grammar::hexdig_value(
0091 it[1]) >= 0);
0092 BOOST_ASSERT(
0093 grammar::hexdig_value(
0094 it[2]) >= 0);
0095 n += 3;
0096 it += 3;
0097 }
0098 }
0099 }
0100 return n;
0101 }
0102
0103
0104
0105 template<class CharSet>
0106 std::size_t
0107 re_encode_unsafe(
0108 char*& dest_,
0109 char const* const end,
0110 core::string_view s,
0111 CharSet const& unreserved,
0112 encoding_opts opt) noexcept
0113 {
0114 char const* const hex =
0115 detail::hexdigs[opt.lower_case];
0116 auto const encode = [end, hex](
0117 char*& dest,
0118 unsigned char c) noexcept
0119 {
0120 ignore_unused(end);
0121 *dest++ = '%';
0122 BOOST_ASSERT(dest != end);
0123 *dest++ = hex[c>>4];
0124 BOOST_ASSERT(dest != end);
0125 *dest++ = hex[c&0xf];
0126 };
0127 ignore_unused(end);
0128
0129 auto dest = dest_;
0130 auto const dest0 = dest;
0131 auto const last = s.end();
0132 std::size_t dn = 0;
0133 auto it = s.begin();
0134
0135 if(opt.space_as_plus)
0136 {
0137 while(it != last)
0138 {
0139 BOOST_ASSERT(dest != end);
0140 if(*it != '%')
0141 {
0142 if(*it == ' ')
0143 {
0144 *dest++ = '+';
0145 }
0146 else if(unreserved(*it))
0147 {
0148 *dest++ = *it;
0149 }
0150 else
0151 {
0152 encode(dest, *it);
0153 dn += 2;
0154 }
0155 ++it;
0156 }
0157 else
0158 {
0159 *dest++ = *it++;
0160 BOOST_ASSERT(dest != end);
0161 *dest++ = *it++;
0162 BOOST_ASSERT(dest != end);
0163 *dest++ = *it++;
0164 dn += 2;
0165 }
0166 }
0167 }
0168 else
0169 {
0170 while(it != last)
0171 {
0172 BOOST_ASSERT(dest != end);
0173 if(*it != '%')
0174 {
0175 if(unreserved(*it))
0176 {
0177 *dest++ = *it;
0178 }
0179 else
0180 {
0181 encode(dest, *it);
0182 dn += 2;
0183 }
0184 ++it;
0185 }
0186 else
0187 {
0188 *dest++ = *it++;
0189 BOOST_ASSERT(dest != end);
0190 *dest++ = *it++;
0191 BOOST_ASSERT(dest != end);
0192 *dest++ = *it++;
0193 dn += 2;
0194 }
0195 }
0196 }
0197 dest_ = dest;
0198 return dest - dest0 - dn;
0199 }
0200
0201 }
0202 }
0203 }
0204
0205 #endif